Phase 843: runGuildMeshQuadEmojiJourney and meshQuadEmojisReady

Four-peer custom emoji fanout contract extends Phase 802 triple emoji slice.

Co-authored-by: Cursor <[email protected]>
This commit is contained in:
Raven Scott
2026-06-04 05:15:57 -04:00
co-authored by Cursor
parent 1f99af8a83
commit 6f57f98a11
3 changed files with 87 additions and 0 deletions
+2
View File
@@ -2,6 +2,8 @@
Agent control plane for Pearcord — send the same IPC messages the UI sends, read `view` snapshots, and run scripted journeys against a **live worker** or an in-process **headless** session.
**Phase 843 (v0.8.810):** `runGuildMeshQuadEmojiJourney` (4-peer custom emoji). Bundle: `npm run test:ci-phase843`.
**Phase 842 (v0.8.809):** `runGuildMeshQuadOfflineRecoveryJourney` (4-peer offline recovery). Bundle: `npm run test:ci-phase842`.
**Phase 841 (v0.8.808):** `runGuildMeshQuadSyncHealthJourney` (4-peer sync health rail). Bundle: `npm run test:ci-phase841`.
+11
View File
@@ -211,6 +211,17 @@ function matchView (view, spec) {
if (view?.meshStabilityStats?.pushHalted) return false
continue
}
if (key === 'meshQuadEmojisReady') {
if (!expected) return true
const peers = Number(view?.stats?.peers) || 0
if (peers < 2) return false
const gid = view?.guild?.id
const rail = gid ? view.guildSyncHealthRail?.[gid] : null
if (rail?.meshBounded) return false
const hasCustom = (view?.guildEmojis || []).some((e) => e?.name && !e.builtin)
if (!hasCustom) return false
continue
}
if (key === 'meshQuadUnreadReady') {
if (!expected) return true
const peers = Number(view?.stats?.peers) || 0
+74
View File
@@ -8323,6 +8323,80 @@ class HeadlessSession {
}
}
/** Phase 843: 4-peer mesh — host custom emoji visible on all three guests. */
async runGuildMeshQuadEmojiJourney () {
const { connectGuildMeshQuad } = require('./mesh-helpers')
const token = `mesh843_${Date.now()}`
const base = path.join(os.tmpdir(), `pearcord-agentctl-emoji843-${Date.now()}`)
const host = new HeadlessSession({ storagePath: path.join(base, 'host') })
const guest1 = new HeadlessSession({ storagePath: path.join(base, 'guest1') })
const guest2 = new HeadlessSession({ storagePath: path.join(base, 'guest2') })
const guest3 = new HeadlessSession({ storagePath: path.join(base, 'guest3') })
await host.start()
await guest1.start()
await guest2.start()
await guest3.start()
try {
await host.registerUser({ username: 'emhost843', displayName: 'Emoji Host 843' })
await host.createGuild({ name: 'Emoji Quad 843', publicListing: false })
await host.wait({ mode: 'guild' }, 45000)
const invite = await host.platform.createInvite().catch(() => null)
const code = invite?.shareCode || invite?.code
if (!code) throw new Error('host invite missing')
await guest1.registerUser({ username: 'emguest843a', displayName: 'Emoji Guest 843a' })
await guest2.registerUser({ username: 'emguest843b', displayName: 'Emoji Guest 843b' })
await guest3.registerUser({ username: 'emguest843c', displayName: 'Emoji Guest 843c' })
await guest1.ipc({ type: 'join-invite', code })
await guest2.ipc({ type: 'join-invite', code })
await guest3.ipc({ type: 'join-invite', code })
await guest1.wait({ mode: 'guild' }, 45000)
await guest2.wait({ mode: 'guild' }, 45000)
await guest3.wait({ mode: 'guild' }, 45000)
await connectGuildMeshQuad(
host.platform,
guest1.platform,
guest2.platform,
guest3.platform,
55000
)
const quadWait = { meshQuadReady: true, membersMin: 4 }
await host.wait(quadWait, 30000)
await guest1.wait(quadWait, 30000)
await guest2.wait(quadWait, 30000)
await guest3.wait(quadWait, 30000)
await host.upsertGuildEmoji({ name: token, glyph: '🎭' })
for (const p of [host.platform, guest1.platform, guest2.platform, guest3.platform]) {
if (typeof p.requestGuildSyncFanout === 'function') {
p.requestGuildSyncFanout()
}
}
const emojiWait = {
meshQuadEmojisReady: true,
guildEmojiNamed: token
}
await guest1.wait(emojiWait, 90000)
await guest2.wait(emojiWait, 90000)
await guest3.wait(emojiWait, 90000)
const g1v = await guest1.refreshView()
const g2v = await guest2.refreshView()
const g3v = await guest3.refreshView()
const hit = (v) => (v.guildEmojis || []).find((e) => e.name === token)
if (!hit(g1v) || !hit(g2v) || !hit(g3v)) {
throw new Error('guest missing custom emoji on quad mesh')
}
return {
emojiName: token,
guest2Glyph: hit(g2v)?.glyph,
guest3Glyph: hit(g3v)?.glyph
}
} finally {
await host.close()
await guest1.close()
await guest2.close()
await guest3.close()
}
}
/** Phase 829: 4-peer mesh — drop one guest, survivors stay synced, rejoin + recovery burst. */
async runGuildMeshQuadChurnRejoinJourney () {
const {