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:
@@ -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 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 816 (v0.8.783):** `runGuildMeshTriplePartitionHealHardenedJourney`, `partitionHealComplete`. Bundle: `npm run test:ci-phase816`.
|
||||
|
||||
@@ -144,6 +144,14 @@ function matchView (view, spec) {
|
||||
if (rail?.meshBounded) return false
|
||||
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') {
|
||||
const n = Number(view?.stats?.peers) || 0
|
||||
if (n !== Number(expected)) return false
|
||||
|
||||
+73
@@ -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. */
|
||||
async runGuildMeshTripleReconnectJourney () {
|
||||
const {
|
||||
|
||||
Reference in New Issue
Block a user