// conformance — does the network hold what we think we published?
// Run: node test/conformance.test.mjs
//
// Both real interop defects of 2026-07-31 were SILENT SUCCESSES: local surfaces green, network empty.
// So the assertions here are about catching that class, and about the opposite failure — reporting an
// ordinary propagation delay as corruption, which would be a silent failure in the other direction.
import { validateRecord, checkConformance, probePost, likedBy, networkFollows } from '../lib/conformance.js'
let pass = 0
const ok = (c, m) => { if (!c) { console.error('FAIL:', m); process.exit(1) } console.log(' ok -', m); pass++ }
const DID = 'did:plc:wj62ebbusln6gxo5azo6ogzo'
const SUBJ = 'at://did:plc:other000000000000000000/app.bsky.feed.post/3kabc'
const NOW = Date.parse('2026-07-31T12:00:00Z')
const OLD = '2026-07-01T00:00:00Z'
const codes = (rs) => rs.map((r) => r.code)
const jsonRes = (body) => ({ ok: true, json: async () => body })
// ── layer 1: structural — the defect that federated 4 likes as nothing ───────────────────────────
{
const bad = { $type: 'app.bsky.feed.like', subject: { uri: SUBJ }, createdAt: OLD }
ok(codes(validateRecord('app.bsky.feed.like', bad)).includes('strongref-no-cid'),
'a strongRef with uri but NO cid is caught — this is the exact shape that passed locally and was rejected by the relay')
const good = { $type: 'app.bsky.feed.like', subject: { uri: SUBJ, cid: 'bafy' }, createdAt: OLD }
ok(validateRecord('app.bsky.feed.like', good).length === 0, 'a complete strongRef is clean')
}
{
const r = { $type: 'app.bsky.feed.post', text: 'x', createdAt: OLD, langs: ['en'], reply: { parent: { uri: SUBJ }, root: { uri: SUBJ, cid: 'b' } } }
ok(codes(validateRecord('app.bsky.feed.post', r)).filter((c) => c === 'strongref-no-cid').length === 1,
'a reply carries TWO strongRefs and each is checked independently')
}
{
ok(codes(validateRecord('app.bsky.feed.like', { subject: { uri: SUBJ, cid: 'b' } })).includes('missing-required'),
'a missing required field is caught')
ok(codes(validateRecord('app.bsky.feed.post', { text: 'x', createdAt: OLD, langs: ['en'], reply: { root: { uri: SUBJ, cid: 'b' } } })).includes('reply-no-parent'),
'a half-formed reply edge is caught')
ok(validateRecord('app.bsky.feed.post', null)[0].code === 'not-an-object', 'garbage is caught, not thrown on')
}
{
const warn = validateRecord('app.bsky.feed.post', { text: 'x', createdAt: OLD })
ok(warn.some((w) => w.code === 'no-langs' && w.warning), 'a langs-less post is a WARNING, not an error — lexicon-valid but dropped by some custom feeds')
}
// ── layer 2: pending vs missing — do NOT report propagation delay as corruption ───────────────────
{
const doFetch = async () => jsonRes({}) // AppView says: no such post
const fresh = { createdAt: new Date(NOW - 60_000).toISOString() }
const stale = { createdAt: OLD }
ok((await probePost(doFetch, DID, 'rk', fresh, { now: NOW })).state === 'pending',
'a RECENT record absent from bsky is pending — the AppView is eventually consistent and the relay non-archival')
ok((await probePost(doFetch, DID, 'rk', stale, { now: NOW })).state === 'missing',
'an OLD record still absent is missing — past the grace window, absence is a finding')
}
{
const doFetch = async () => jsonRes({ thread: { post: { uri: 'x' } } })
ok((await probePost(doFetch, DID, 'rk', { createdAt: OLD }, { now: NOW })).state === 'ok', 'a post bsky holds is ok')
}
{
const doFetch = async () => ({ ok: false })
ok((await probePost(doFetch, DID, 'rk', { createdAt: OLD }, { now: NOW })).state === 'missing', 'an unreachable AppView degrades to a finding, never a throw')
}
{
// A REPAIRED record keeps its original createdAt but was just re-signed. Without republishedAfter it
// reads as missing seconds after the repair — observed live on 2026-07-31.
const doFetch = async () => jsonRes({})
const stale = { createdAt: OLD }
ok((await probePost(doFetch, DID, 'rk', stale, { now: NOW })).state === 'missing', 'an old record reads missing by default')
ok((await probePost(doFetch, DID, 'rk', stale, { now: NOW, republishedAfter: NOW - 60_000 })).state === 'pending',
'but a record RE-SIGNED just now is pending despite an old createdAt — propagation is not corruption')
}
// ── the probes ───────────────────────────────────────────────────────────────────────────────────
{
const doFetch = async (u) => jsonRes(u.includes('getLikes') ? { likes: [{ actor: { did: DID } }] } : {})
ok((await likedBy(doFetch, SUBJ, DID)) === true, 'likedBy sees our did among the likers')
ok((await likedBy(async () => jsonRes({ likes: [] }), SUBJ, DID)) === false, 'and its absence')
ok((await likedBy(async () => ({ ok: false }), SUBJ, DID)) === null, 'an unavailable probe is null — distinct from a negative')
}
{
const net = await networkFollows(async () => jsonRes({ follows: [{ did: 'did:plc:a' }] }), DID)
ok(net.has('did:plc:a'), 'follows come back as a set for one set-difference')
}
// ── the whole check ──────────────────────────────────────────────────────────────────────────────
const fixture = {
'app.bsky.feed.post': [{ rkey: 'p1', record: { $type: 'app.bsky.feed.post', text: 'hi', createdAt: OLD, langs: ['en'] } }],
'app.bsky.feed.like': [
{ rkey: 'l1', record: { $type: 'app.bsky.feed.like', subject: { uri: SUBJ }, createdAt: OLD } }, // no cid
{ rkey: 'l2', record: { $type: 'app.bsky.feed.like', subject: { uri: SUBJ, cid: 'bafy' }, createdAt: OLD } }
],
'app.bsky.feed.repost': [],
'app.bsky.graph.follow': [{ rkey: 'f1', record: { subject: 'did:plc:nope', createdAt: OLD } }]
}
{
const r = await checkConformance({ did: DID, listRecords: async (c) => fixture[c] || [] }) // offline
ok(r.summary.structuralErrors === 1, 'the offline layer alone finds the invalid like')
ok(r.summary.networkChecked === false, 'and says plainly that it did not check the network')
ok(r.structural[0].code === 'strongref-no-cid' && r.structural[0].rkey === 'l1', 'naming the exact record')
}
{
let calls = 0
const doFetch = async (u) => {
calls++
if (u.includes('getPostThread')) return jsonRes({}) // bsky lacks our post
if (u.includes('getFollows')) return jsonRes({ follows: [] }) // and our follow
if (u.includes('getLikes')) return jsonRes({ likes: [] }) // and our like
return jsonRes({})
}
const r = await checkConformance({ did: DID, listRecords: async (c) => fixture[c] || [], doFetch, now: NOW })
ok(r.summary.networkMissing >= 3, 'the network layer finds records bsky does not index across all three collections')
ok(r.network.some((n) => n.collection === 'app.bsky.graph.follow'), 'including follows, via one set-difference')
ok(calls <= 4, `likes are grouped by SUBJECT so N likes on one post cost ONE call (${calls} calls total)`)
}
{
// Two likes on the SAME subject must not become two probes.
let likeCalls = 0
const many = { 'app.bsky.feed.like': [1, 2, 3, 4].map((i) => ({ rkey: 'l' + i, record: { subject: { uri: SUBJ, cid: 'b' }, createdAt: OLD } })) }
await checkConformance({
did: DID,
listRecords: async (c) => many[c] || [],
doFetch: async (u) => { if (u.includes('getLikes')) likeCalls++; return jsonRes({ likes: [{ actor: { did: DID } }] }) },
now: NOW
})
ok(likeCalls === 1, 'four likes on one subject = one getLikes call')
}
{
const r = await checkConformance({ did: DID, listRecords: async () => { throw new Error('store down') } })
ok(r.summary.checked === 0, 'a failed listRecords is skipped per-collection, not fatal')
}
console.log(`\nCONFORMANCE OK: ${pass} assertions`)