Phase 818: runGuildMeshTripleSyncHealthJourney (v0.8.785).

Adds guildSyncHealthRailPresent matcher and triple-peer sync health
contract after _refreshGuildSyncHealthCounts and mesh fanout.

Co-authored-by: Cursor <[email protected]>
This commit is contained in:
Raven Scott
2026-06-03 23:54:32 -04:00
co-authored by Cursor
parent 84eaef5f4b
commit 733dba6c7e
3 changed files with 83 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. 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 818 (v0.8.785):** `runGuildMeshTripleSyncHealthJourney` (3-peer sync health rail). Bundle: `npm run test:ci-phase818`.
**Phase 817 (v0.8.784):** `runGuildMeshTripleOfflineRecoveryJourney` (3-peer offline recovery). Bundle: `npm run test:ci-phase817`. **Phase 817 (v0.8.784):** `runGuildMeshTripleOfflineRecoveryJourney` (3-peer offline recovery). Bundle: `npm run test:ci-phase817`.
**Phase 816 (v0.8.783):** `runGuildMeshTriplePartitionHealHardenedJourney`, `partitionHealComplete`. Bundle: `npm run test:ci-phase816`. **Phase 816 (v0.8.783):** `runGuildMeshTriplePartitionHealHardenedJourney`, `partitionHealComplete`. Bundle: `npm run test:ci-phase816`.
+8
View File
@@ -144,6 +144,14 @@ function matchView (view, spec) {
if (rail?.meshBounded) return false if (rail?.meshBounded) return false
return true return true
} }
if (key === 'guildSyncHealthRailPresent') {
if (!expected) return true
const gid = view?.guild?.id
if (!gid) return false
const rail = view.guildSyncHealthRail?.[gid]
if (!rail || typeof rail !== 'object') return false
continue
}
if (key === 'meshPeersExact') { if (key === 'meshPeersExact') {
const n = Number(view?.stats?.peers) || 0 const n = Number(view?.stats?.peers) || 0
if (n !== Number(expected)) return false if (n !== Number(expected)) return false
+73
View File
@@ -6141,6 +6141,79 @@ class HeadlessSession {
} }
} }
/** Phase 818: 3-peer mesh — sync health rail on host + both guests after fanout. */
async runGuildMeshTripleSyncHealthJourney () {
const { connectGuildMeshTriple } = require('./mesh-helpers')
const token = `health818-${Date.now()}`
const base = path.join(os.tmpdir(), `pearcord-agentctl-health818-${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') })
await host.start()
await guest1.start()
await guest2.start()
try {
await host.registerUser({ username: 'hlthhost818', displayName: 'Health Host 818' })
await host.createGuild({ name: 'Sync Health Triple 818', 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: 'hlthguest818a', displayName: 'Health Guest 818a' })
await guest2.registerUser({ username: 'hlthguest818b', displayName: 'Health Guest 818b' })
await guest1.ipc({ type: 'join-invite', code })
await guest2.ipc({ type: 'join-invite', code })
await guest1.wait({ mode: 'guild' }, 45000)
await guest2.wait({ mode: 'guild' }, 45000)
await connectGuildMeshTriple(
host.platform,
guest1.platform,
guest2.platform,
50000
)
for (const sess of [host, guest1, guest2]) {
const gid = (await sess.refreshView()).guild?.id
if (gid && typeof sess.platform._refreshGuildSyncHealthCounts === 'function') {
await sess.platform._refreshGuildSyncHealthCounts(gid).catch(() => null)
}
if (typeof sess.platform.requestGuildSyncFanout === 'function') {
sess.platform.requestGuildSyncFanout()
}
}
const readyWait = {
meshReconnectReady: true,
meshPeersMin: 1,
guildSyncHealthRailPresent: true
}
await host.wait(readyWait, 90000)
await guest1.wait(readyWait, 90000)
await guest2.wait(readyWait, 90000)
await host.sendGuildMessage(token)
const msgWait = { activeChannelMessageIncludes: token }
await guest1.wait(msgWait, 90000)
await guest2.wait(msgWait, 90000)
const hv = await host.refreshView()
const g1v = await guest1.refreshView()
const g2v = await guest2.refreshView()
const gid = hv.guild?.id
return {
token,
hostPeers: hv.stats?.peers,
guest1Peers: g1v.stats?.peers,
guest2Peers: g2v.stats?.peers,
hostRail: gid ? !!hv.guildSyncHealthRail?.[gid] : false,
guest1Rail: gid ? !!g1v.guildSyncHealthRail?.[gid] : false,
guest2Rail: gid ? !!g2v.guildSyncHealthRail?.[gid] : false,
guest1Bounded: g1v.guildSyncHealthRail?.[gid]?.meshBounded,
guest2Bounded: g2v.guildSyncHealthRail?.[gid]?.meshBounded
}
} finally {
await host.close()
await guest1.close()
await guest2.close()
}
}
/** Phase 809: 3-peer mesh disconnect + reconnect; both guests recover sync rail. */ /** Phase 809: 3-peer mesh disconnect + reconnect; both guests recover sync rail. */
async runGuildMeshTripleReconnectJourney () { async runGuildMeshTripleReconnectJourney () {
const { const {