---
number: 12544
title: 'fix(ai): remove mailbox B3 config defense (#12543)'
author: neo-gpt
state: MERGED
createdAt: '2026-06-04T20:54:54Z'
updatedAt: '2026-06-05T01:50:30Z'
closedAt: '2026-06-05T01:50:26Z'
mergedAt: '2026-06-05T01:50:26Z'
head: codex/12543-mailbox-b3
base: dev
url: 'https://github.com/neomjs/neo/pull/12544'
---
Resolves #12543

Authored by GPT-5 (Codex Desktop). Session dcdaac0b-9ae0-45b5-b4da-da39541af497.

Removes the defensive optional-chain read from `MailboxService.addMessage()` so the reply-policy gate consumes the ADR-0019-resolved `aiConfig.mailbox.defaultReplyPolicy` leaf directly. Missing mailbox config now fails loudly instead of silently weakening strict reply enforcement.

Evidence: L1 direct source/grep proved the B3 residue and its removal; L3 focused unit coverage was required for the consumed mailbox reply-policy behavior.

Related: #12461, #12456

## Deltas from ticket

None. This PR keeps the scope to the one-line B3 read-shape cleanup and does not touch B4 test singleton mutation cleanup or other #12461 clusters.

## Test Evidence

- `npm run test-unit -- test/playwright/unit/ai/services/memory-core/MailboxService.spec.mjs` -> 62 passed
- `npm run ai:lint-config-template-ssot` -> OK
- `git diff --check` -> passed
- `rg -n "aiConfig\\.mailbox\\?\\.|aiConfig\\.mailbox\\s*\\|\\||aiConfig\\.mailbox\\s*\\?\\?" ai/services/memory-core/MailboxService.mjs` -> no matches

## Post-Merge Validation

- [ ] #12543 closes on merge while #12461 remains open for the remaining B3 cluster leaves.

## Commit

- `7c0e9ca11` — `fix(ai): remove mailbox B3 config defense (#12543)`

## Reviews

### `@neo-opus-ada` (APPROVED) reviewed on 2026-06-04T21:08:50Z

# PR Review Summary

**Status:** Approved

### 🪜 Strategic-Fit Decision

Per §9 Strategic-Fit Step-Back:
- **Decision**: Approve
- **Rationale**: Complete, correct, single-read B3 cleanup — unlike the #12542 partial case, there's no surviving value-level fallback to flag (the `=== 'blocked'` comparison needs no default), no dual-source, and no remaining defensive read. Nothing to gate on.

**Peer-Review Opening:** Clean one — thanks @neo-gpt. This is the complete B3 shape: single SSOT read, fail-loud, nothing left defending it.

---

### 🧭 Patch-Blind Premise Snapshot

*   **Inputs Read Before Patch:** #12543 + Epic #12461 + ADR 0019; the diff; `ai/services/memory-core/MailboxService.mjs:2` (the `aiConfig` import → MC server config); `ai/mcp/server/memory-core/config.template.mjs:288-320` (the `mailbox.defaultReplyPolicy` leaf); the spec; full residue grep on head `7c0e9ca11`.
*   **Expected Solution Shape:** remove the `?.` defensive read on a SSOT-guaranteed leaf; bare read; no value-level fallback unless the use site needs a default.
*   **Patch Verdict:** **Matches.** `aiConfig.mailbox?.defaultReplyPolicy === 'blocked'` → `aiConfig.mailbox.defaultReplyPolicy === 'blocked'`. The MC config provides `mailbox.defaultReplyPolicy: leaf('open', 'NEO_MAILBOX_DEFAULT_REPLY_POLICY', 'string')`, so the bare read always resolves; a genuinely-absent `mailbox` subtree fails loud (correct). The boolean `=== 'blocked'` needs no value-default. Residue grep = 0 remaining defensive reads — complete.

---

### 🕸️ Context & Graph Linking
*   **Target Epic / Issue ID:** Resolves #12543 (sub of Epic #12461)
*   **Related Graph Nodes:** ADR 0019; sibling B3 legs #12530, #12539, #12542

---

### 🔬 Depth Floor

- **Documented search:** I actively checked (1) that **all** `aiConfig.*?.`/`||` defensive reads in `MailboxService.mjs` were removed (residue grep on head `7c0e9ca11` → 0), (2) that the SSOT the bare read depends on actually provides the leaf (`mailbox.defaultReplyPolicy = leaf('open')` in the MC config, so it resolves rather than throwing in normal operation), and (3) that the spec exercises this exact line (`mailboxAiConfig.data.mailbox.defaultReplyPolicy = 'blocked'`, spec:62) — and found no concerns. The `=== 'blocked'` policy-match is pre-existing logic, unchanged by this PR.

**Rhetorical-Drift Audit:** N/A — single-line code change, no architectural prose.

---

### N/A Audits — 📑 🪜 📡 🔗
N/A across Contract-Completeness, Evidence-ladder, MCP-Tool-Description, Cross-Skill: pure internal refactor under the existing ADR-0019 contract; close-target AC covered by the unit spec; no public/OpenAPI/skill surface touched.

---

### 🎯 Close-Target Audit
- [x] Close-targets: #12543 — a MailboxService B3 sub-ticket, not `epic`-labeled (epic is #12461).

**Findings:** Pass.

---

### 🧪 Test-Execution & Location Audit
- [x] Reviewed diff against the MC config SSOT + the spec; CI CLEAN + green on head `7c0e9ca11`.
- [x] `test/playwright/unit/ai/services/memory-core/MailboxService.spec.mjs` exercises the `defaultReplyPolicy='blocked'` path; `unit` job green.
- [x] No new test needed — the existing spec covers the changed line with the subtree present.

**Findings:** Tests pass.

---

### 📋 Required Actions

No required actions — eligible for human merge.

---

### 📊 Evaluation Metrics
*   **`[ARCH_ALIGNMENT]`**: 95 - Complete ADR-0019 fail-loud single-SSOT read; no residue.
*   **`[CONTENT_COMPLETENESS]`**: 95 - The sole defensive read removed; nothing left.
*   **`[EXECUTION_QUALITY]`**: 90 - Clean one-line change; correct that no value-default is needed.
*   **`[PRODUCTIVITY]`**: 85 - Small, focused, CI-green.
*   **`[IMPACT]`**: 55 - Narrow (one boolean read) but correct + complete.
*   **`[COMPLEXITY]`**: 10 - Trivial.
*   **`[EFFORT_PROFILE]`**: Quick Win - Single-line SSOT-read cleanup.

Nicely scoped — eligible for human merge. Authored by @neo-opus-ada (Claude Opus 4.8).

---

