=== install deps (root closure) (ok, 838ms) ===

added 31 packages, and audited 36 packages in 691ms

found 0 vulnerabilities


=== vendor file: siblings into the closure (ok, 26840ms) ===
siblings (derived from package.json): ap-bridge=ap-bridge atproto-bridge=atproto-bridge atproto-identity=atproto-identity hyper-svc=hyper-svc
  ap-bridge (ap-bridge): 4e096f0 ok (on: master )
  atproto-bridge (atproto-bridge): 7ad02e9 ok (on: main )
  atproto-identity (atproto-identity): 6be1688 ok (on: master )
  hyper-svc (hyper-svc): 53c3e79 ok (on: main )


=== every direct import is declared (ok, 552ms) ===
  ok: ap-bridge
  ok: ap-bridge
  ok: atproto-bridge
  ok: atproto-bridge
  ok: atproto-bridge
  ok: atproto-bridge
  ok: atproto-identity
  ok: atproto-identity
  ok: b4a
  ok: bare-fs
  ok: bare-net
  ok: bare-os
  ok: bare-path
  ok: bare-process
  ok: hyper-svc
  ok: @ipld/dag-cbor


=== tests (offline, against the vendored closure) (ok, 51967ms) ===
test-only devDependencies: @jridgewell/resolve-uri@3.1.2 @jridgewell/sourcemap-codec@1.6.0 @jridgewell/trace-mapping@0.3.31 @types/istanbul-lib-coverage@2.0.6 bare-addon-resolve@1.11.0 bare-ansi-escapes@2.2.3 bare-assert@1.2.0 bare-bundle@1.11.0 bare-cov@1.2.3 bare-crypto@1.15.4 bare-debug-log@2.0.0 bare-encoding@1.0.3 bare-format@1.0.2 bare-http-parser@2.1.4 bare-http1@4.6.2 bare-https@3.1.0 bare-inspect@3.1.10 bare-inspector@6.1.0 bare-module@6.4.0 bare-module-lexer@1.7.0 bare-module-resolve@1.12.6 bare-semver@1.1.0 bare-stylize@0.0.1 bare-subprocess@5.2.3 bare-tls@3.1.11 bare-type@1.1.1 bare-type-stripper@0.1.7 bare-utils@1.6.0 bare-v8-to-istanbul@1.0.4 bare-ws@3.2.0 bip39-mnemonic@2.5.0 brittle@3.19.1 compact-encoding@3.5.2 convert-source-map@2.0.0 error-stack-parser@2.1.4 globbie@1.0.6 keet-identity-key@3.2.0 nanoassert@2.0.0 paparam@1.14.0 picomatch@4.0.7 require-addon@1.3.0 same-object@1.0.2 sodium-hmac@2.1.0 sodium-native@5.1.0 sodium-universal@5.0.1 stackframe@1.3.4 test-tmp@1.4.0 tmatch@5.0.0 v8-to-istanbul@9.3.0 which-runtime@1.4.0
overlaid for the test run only: bare-addon-resolve bare-ansi-escapes bare-assert bare-bundle bare-cov bare-crypto bare-debug-log bare-encoding bare-format bare-http1 bare-http-parser bare-https bare-inspect bare-inspector bare-module bare-module-lexer bare-module-resolve bare-semver bare-stylize bare-subprocess bare-tls bare-type bare-type-stripper bare-utils bare-v8-to-istanbul bare-ws bip39-mnemonic brittle compact-encoding convert-source-map error-stack-parser globbie @jridgewell/resolve-uri @jridgewell/sourcemap-codec @jridgewell/trace-mapping keet-identity-key nanoassert paparam picomatch require-addon same-object sodium-hmac sodium-native sodium-universal stackframe test-tmp tmatch @types/istanbul-lib-coverage v8-to-istanbul which-runtime
TAP version 13

# ★ healthy: nothing open
    ok 1 - should deep equal
ok 1 - ★ healthy: nothing open # time = 2ms

# ⛔ relay newer than us: critical at once, with the emit-sync command and the caution
    ok 1 - opened on the first check
    ok 2 - should be equal
    ok 3 - names the command
    ok 4 - and what to confirm first
ok 2 - ⛔ relay newer than us: critical at once, with the emit-sync command and the caution # time = 0ms

# ⛔ the relay has us offline: critical at once
    ok 1 - expected truthy value
ok 3 - ⛔ the relay has us offline: critical at once # time = 0ms

# PLC pointing elsewhere: critical at once; a role down: critical at once
    ok 1 - expected truthy value
    ok 2 - expected truthy value
ok 4 - PLC pointing elsewhere: critical at once; a role down: critical at once # time = 1ms

# a blip is not an alert: relay behind / AppView unresolved need two checks in a row
    ok 1 - first sighting: watched, not open
    ok 2 - second check in a row: open
ok 5 - a blip is not an alert: relay behind / AppView unresolved need two checks in a row # time = 0ms

# peers offline must last an hour before it is an alert
    ok 1 - 59 minutes: not yet
    ok 2 - 61 minutes: open
ok 6 - peers offline must last an hour before it is an alert # time = 0ms

# fediverse: dead deliveries and a server failing repeatedly
    ok 1 - expected truthy value
    ok 2 - expected truthy value
ok 7 - fediverse: dead deliveries and a server failing repeatedly # time = 0ms

# lens: a member the membrane does not front, and a member it cannot index
    ok 1 - expected truthy value
    ok 2 - expected truthy value
ok 8 - lens: a member the membrane does not front, and a member it cannot index # time = 1ms

# memory over the ceiling (a probe leak would show here)
    ok 1 - expected truthy value
ok 9 - memory over the ceiling (a probe leak would show here) # time = 0ms

# ★ open since is kept across checks; a cleared condition resolves and is reported once
    ok 1 - since = first sighting, not the latest check
    ok 2 - should deep equal
    ok 3 - reported as resolved
    ok 4 - should be equal
    ok 5 - and only once
ok 10 - ★ open since is kept across checks; a cleared condition resolves and is reported once # time = 0ms

# a check that could not reach bsky does not resolve bsky alerts it could not see
    ok 1 - still open: nothing showed it cleared
ok 11 - a check that could not reach bsky does not resolve bsky alerts it could not see # time = 0ms

# parseParams: key=value pairs, with numbers, booleans and JSON values typed
    ok 1 - should deep equal
    ok 2 - should deep equal
    ok 3 - a bare word is refused, not guessed at
ok 12 - parseParams: key=value pairs, with numbers, booleans and JSON values typed # time = 2ms

# ★ a verb is called on the socket and its reply printed
    ok 1 - should be equal
    ok 2 - should deep equal
    ok 3 - the reply, as readable JSON
ok 13 - ★ a verb is called on the socket and its reply printed # time = 0ms

# help lists the verbs the RUNNING gateway serves
    ok 1 - expected truthy value
ok 14 - help lists the verbs the RUNNING gateway serves # time = 0ms

# ⛔ a gateway that is not running says so, and how to start it — exit 1, nothing booted
    ok 1 - should be equal
    ok 2 - expected truthy value
ok 15 - ⛔ a gateway that is not running says so, and how to start it — exit 1, nothing booted # time = 1ms

# a verb the gateway does not serve fails with the gateway's own error
    ok 1 - should be equal
    ok 2 - expected truthy value
ok 16 - a verb the gateway does not serve fails with the gateway's own error # time = 0ms

# ★ metrics renders as a readable summary: roles, bsky, peers, problems
    ok 1 - a down role, with why
    ok 2 - bsky relay status and seq
    ok 3 - per DID: handle and relay sync
    ok 4 - peers: live of cached fronts
    ok 5 - last append as an age, not a timestamp
    ok 6 - the named problems, last
ok 17 - ★ metrics renders as a readable summary: roles, bsky, peers, problems # time = 0ms

# metrics --json prints the raw answer
    ok 1 - should be equal
ok 18 - metrics --json prints the raw answer # time = 0ms

# alerts render first, each with its fix
    ok 1 - expected truthy value
    ok 2 - expected truthy value
    ok 3 - how long it has been open
ok 19 - alerts render first, each with its fix # time = 1ms

# ★ both roles serve from one process
    ok 1 - the membrane answers
    ok 2 - the fediverse actor answers
    ok 3 - status ok
    ok 4 - and names both roles
ok 20 - ★ both roles serve from one process # time = 1471ms

# ★ one handler map carries both roles' verbs, and nothing collides
    ok 1 - membrane: list-fronted
    ok 2 - membrane: diagnose
    ok 3 - membrane: probe-front
    ok 4 - membrane: drop-front
    ok 5 - membrane: allow-front
    ok 6 - membrane: forget-did
    ok 7 - membrane: set-seq-base
    ok 8 - membrane: emit-sync
    ok 9 - membrane: resolve-handle
    ok 10 - membrane: list-repos
    ok 11 - fediverse: invite
    ok 12 - fediverse: notifications
    ok 13 - fediverse: reproject
    ok 14 - release-ready belongs to the process owner, not to a role
    ok 15 - a membrane verb answers
    ok 16 - a fediverse verb answers
ok 21 - ★ one handler map carries both roles' verbs, and nothing collides # time = 435ms

# ⛔ a role that fails to start is reported down, and the other keeps serving
    ok 1 - the membrane still serves
    ok 2 - the fediverse role is not running
    ok 3 - status says it is down
    ok 4 - and why
    ok 5 - and a down role offers no verbs
ok 22 - ⛔ a role that fails to start is reported down, and the other keeps serving # time = 136ms

# a config the entry could not load arrives as an Error and marks only that role down
    ok 1 - the reason is the config error, verbatim
    ok 2 - the membrane is up
ok 23 - a config the entry could not load arrives as an Error and marks only that role down # time = 109ms

# ⛔ if every requested role fails, the gateway refuses to start
    ok 1 - should reject
ok 24 - ⛔ if every requested role fails, the gateway refuses to start # time = 1ms

# ⛔ an unknown role is refused rather than ignored
    ok 1 - should reject
ok 25 - ⛔ an unknown role is refused rather than ignored # time = 0ms

# the stop steps free everything: the same ports start again in one process
    ok 1 - roles stop in reverse start order
    ok 2 - should be equal
    ok 3 - should be equal
    ok 4 - the published bridgeKey survives a restart
    ok 5 - and so does the membrane's swarm identity
ok 26 - the stop steps free everything: the same ports start again in one process # time = 670ms

# ★ metrics: process, roles, membrane, fediverse and bsky in one answer
    ok 1 - process uptime and RSS
    ok 2 - should be equal
    ok 3 - should be equal
    ok 4 - the membrane section is the role's own metrics
    ok 5 - and so is the fediverse section
    ok 6 - bsky's view, through the probes
    ok 7 - probed for the membrane's own host (from serverDid)
ok 27 - ★ metrics: process, roles, membrane, fediverse and bsky in one answer # time = 427ms

# metrics still answers with a role down, and names it
    ok 1 - should be equal
    ok 2 - should be equal
    ok 3 - no section for a role that is not running
    ok 4 - the running role still reports
ok 28 - metrics still answers with a role down, and names it # time = 136ms

# ⛔ the lens without a running membrane is down, with the reason — it serves THROUGH the membrane
    ok 1 - expected falsy value
    ok 2 - the lens needs the membrane role (start it before the lens)
ok 29 - ⛔ the lens without a running membrane is down, with the reason — it serves THROUGH the membrane # time = 313ms

# ★ alerts: with the watcher on, `alerts refresh=true` checks now and `metrics` carries the result
    ok 1 - the relay-offline alert is open
    ok 2 - expected truthy value
    ok 3 - metrics carries the alerts
    ok 4 - the watcher stops before any role
ok 30 - ★ alerts: with the watcher on, `alerts refresh=true` checks now and `metrics` carries the result # time = 128ms

# ★ the status page is registered on the fediverse role's admin surface and renders every role
    ok 1 - expected truthy value
    ok 2 - should be equal
    ok 3 - Roles
    ok 4 - Served DIDs
    ok 5 - Fediverse
    ok 6 - membrane
    ok 7 - fediverse
ok 31 - ★ the status page is registered on the fediverse role's admin surface and renders every role # time = 360ms

# ★ the public page is served on the membrane's own host only
    ok 1 - registered at /
    ok 2 - and /status
    ok 3 - a handle host: declined, falls through as before
    ok 4 - should be equal
    ok 5 - expected truthy value
ok 32 - ★ the public page is served on the membrane's own host only # time = 124ms

# ★ the lens role gets the labels module (with a state dir) and the member projector (with a labeler socket)
    ok 1 - lens up
    ok 2 - labels served from the gateway's own log
    ok 3 - the member projector runs
ok 33 - ★ the lens role gets the labels module (with a state dir) and the member projector (with a labeler socket) # time = 411ms

# without a state dir or a labeler socket, the lens runs as before
    ok 1 - should be equal
    ok 2 - should be equal
ok 34 - without a state dir or a labeler socket, the lens runs as before # time = 94ms

# ★ a front's verified labels are served by queryLabels, in favela-web's wire shape
    ok 1 - should be equal
    ok 2 - should be equal
    ok 3 - should be equal
    ok 4 - should be equal
    ok 5 - sig as { $bytes } (base64)
    ok 6 - no cursor when the page is the whole set
ok 35 - ★ a front's verified labels are served by queryLabels, in favela-web's wire shape # time = 37ms

# uriPatterns: exact and `*` suffix; sources filter; numeric cursor
    ok 1 - exact
    ok 2 - suffix wildcard
    ok 3 - sources filter
    ok 4 - should be equal
    ok 5 - should be equal
    ok 6 - should be equal
    ok 7 - expected falsy value
ok 36 - uriPatterns: exact and `*` suffix; sources filter; numeric cursor # time = 23ms

# ⛔ a label that does not verify against its src DID's key is never served
    ok 1 - only the verified one
    ok 2 - and the two rejects are counted
ok 37 - ⛔ a label that does not verify against its src DID's key is never served # time = 23ms

# a new label on the front is picked up live; the same label from two co-owners is kept once
    ok 1 - deduplicated by bytes
    ok 2 - the append arrived
ok 38 - a new label on the front is picked up live; the same label from two co-owners is kept once # time = 44ms

# ★ the log persists: the same seq after a restart, whatever order the fronts arrive in
    ok 1 - loaded from the state dir before any front
    ok 2 - same order as before; nothing duplicated
ok 39 - ★ the log persists: the same seq after a restart, whatever order the fronts arrive in # time = 45ms

# ★ subscribeLabels: replay from the cursor, then the live tail, one label per frame
    ok 1 - cursor=1: only seq 2 is replayed
    ok 2 - #labels header
    ok 3 - should be equal
    ok 4 - should be equal
    ok 5 - should be equal
    ok 6 - sig as raw bytes on the CBOR wire
    ok 7 - live tail
    ok 8 - should be equal
    ok 9 - nothing after the client left
ok 40 - ★ subscribeLabels: replay from the cursor, then the live tail, one label per frame # time = 89ms

# subscribeLabels: a cursor past the head gets a FutureCursor error frame first
    ok 1 - expected truthy value
    ok 2 - should be equal
ok 41 - subscribeLabels: a cursor past the head gets a FutureCursor error frame first # time = 21ms

# ★ the skeleton: members' posts, newest createdAt first, TID rkeys only
    ok 1 - should be equal
    ok 2 - self.hello is not a TID, so it is not in the feed
    ok 3 - exhausted: cursor ABSENT, never null
ok 42 - ★ the skeleton: members' posts, newest createdAt first, TID rkeys only # time = 4ms

# ★ pagination: pages concatenate to the whole feed, and only the last lacks a cursor
    ok 1 - should be equal
    ok 2 - a string cursor while more remain
    ok 3 - should be equal
    ok 4 - expected falsy value
    ok 5 - the cursor is opaque text (favela-web's carried NUL bytes)
ok 43 - ★ pagination: pages concatenate to the whole feed, and only the last lacks a cursor # time = 1ms

# limit: default 50, at most 100
    ok 1 - clamped, never an error
ok 44 - limit: default 50, at most 100 # time = 1ms

# ⛔ an unknown feed is UnsupportedAlgorithm (400), as the feed-generator contract says
    ok 1 - should be equal
    ok 2 - should be equal
ok 45 - ⛔ an unknown feed is UnsupportedAlgorithm (400), as the feed-generator contract says # time = 1ms

# describeFeedGenerator names the community DID (the lexicon requires `did`)
    ok 1 - should deep equal
ok 46 - describeFeedGenerator names the community DID (the lexicon requires `did`) # time = 1ms

# ⛔ requests never rebuild the index; a member whose head MOVED is re-read on the next relay append
    ok 1 - two skeleton requests, zero repo reads
    ok 2 - no head moved: no re-read
    ok 3 - wj62's head moved: re-read
    ok 4 - and its new post leads the feed
ok 47 - ⛔ requests never rebuild the index; a member whose head MOVED is re-read on the next relay append # time = 101ms

# a member removed from the room leaves the feed
    ok 1 - only wj62 remains
ok 48 - a member removed from the room leaves the feed # time = 0ms

# a member the membrane does not front is reported, not silently missing
    ok 1 - should deep equal
    ok 2 - should be equal
    ok 3 - indexed posts for the fronted members
    ok 4 - should be equal
    ok 5 - should be equal
ok 49 - a member the membrane does not front is reported, not silently missing # time = 0ms

# labels: queryLabels answers an empty, valid set; subscribeLabels is served
    ok 1 - should deep equal
    ok 2 - expected truthy value
ok 50 - labels: queryLabels answers an empty, valid set; subscribeLabels is served # time = 1ms

# stop removes every registered method — a stopped lens serves nothing
    ok 1 - should be equal
    ok 2 - should be equal
ok 51 - stop removes every registered method — a stopped lens serves nothing # time = 0ms

# ★ with labels injected: the real queryLabels is served, the community DID's front is watched
    ok 1 - should be equal
    ok 2 - the labels module answers, not the empty placeholder
    ok 3 - the community DID's front is handed to the labels module
    ok 4 - should deep equal
ok 52 - ★ with labels injected: the real queryLabels is served, the community DID's front is watched # time = 22ms

# ★ with a projector: every roster change is applied, with the community DID
    ok 1 - should deep equal
    ok 2 - a member leaving is applied too
    ok 3 - should deep equal
ok 53 - ★ with a projector: every roster change is applied, with the community DID # time = 1ms

# ⛔ the community DID gaining a label core re-runs the projector; another DID does not
    ok 1 - the boot run
    ok 2 - a member DID's label core is not the labeler coming online
    ok 3 - the community DID's label core re-runs the projector
    ok 4 - with the current roster
ok 54 - ⛔ the community DID gaining a label core re-runs the projector; another DID does not # time = 1ms

# stop unsubscribes from onLabels — a stopped lens projects nothing
    ok 1 - should be equal
ok 55 - stop unsubscribes from onLabels — a stopped lens projects nothing # time = 0ms

# ★ each member gets `<feed>-member`; a member who left is negated
    ok 1 - members labelled, the old member not
    ok 2 - the old member is negated, not deleted
    ok 3 - labels of other values are not touched
    ok 4 - should deep equal
ok 56 - ★ each member gets `<feed>-member`; a member who left is negated # time = 2ms

# idempotent: the same roster again writes nothing
    ok 1 - should deep equal
ok 57 - idempotent: the same roster again writes nothing # time = 0ms

# ⛔ an empty roster negates nothing (the room has not replicated yet)
    ok 1 - should be equal
    ok 2 - should deep equal
    ok 3 - no write at all
ok 58 - ⛔ an empty roster negates nothing (the room has not replicated yet) # time = 0ms

# ⛔ a socket serving a different DID is refused — no write
    ok 1 - skipped, naming the DID it found
    ok 2 - expected falsy value
    ok 3 - and the metrics say why
ok 59 - ⛔ a socket serving a different DID is refused — no write # time = 1ms

# no community DID yet: skipped, nothing called
    ok 1 - expected truthy value
    ok 2 - should be equal
ok 60 - no community DID yet: skipped, nothing called # time = 0ms

# the socket being down is reported, not thrown
    ok 1 - expected truthy value
    ok 2 - expected truthy value
ok 61 - the socket being down is reported, not thrown # time = 0ms

# ★ alerts come first, critical marked, each with its fix
    ok 1 - should be equal
    ok 2 - before every other section
    ok 3 - the fix
    ok 4 - how long it has been open
    ok 5 - recently resolved is listed too
ok 62 - ★ alerts come first, critical marked, each with its fix # time = 1ms

# ⛔ everything that came from outside is escaped
    ok 1 - alert detail escaped
    ok 2 - role error escaped
    ok 3 - expected truthy value
ok 63 - ⛔ everything that came from outside is escaped # time = 0ms

# every section is present: roles, bsky, served DIDs, lens, fediverse, process
    ok 1 - Roles
    ok 2 - bsky
    ok 3 - Served DIDs
    ok 4 - Lens
    ok 5 - Fediverse
    ok 6 - p2p.7rnx.net
    ok 7 - in sync
    ok 8 - 1/2 live
    ok 9 - 299 posts
    ok 10 - 172 delivered
    ok 11 - prsm.space
    ok 12 - HTTP 502
    ok 13 - 280 MB
    ok 14 - the down role is visible
ok 64 - every section is present: roles, bsky, served DIDs, lens, fediverse, process # time = 1ms

# a gateway with only the membrane still renders (missing sections are omitted, not broken)
    ok 1 - expected truthy value
    ok 2 - expected falsy value
    ok 3 - says what it could not show
ok 65 - a gateway with only the membrane still renders (missing sections are omitted, not broken) # time = 1ms

# ★ all green: relay active and in sync, PLC points here, the AppView resolves
    ok 1 - should be equal
    ok 2 - should be equal
    ok 3 - should be equal
    ok 4 - the relay holds the head we serve
    ok 5 - should be equal
    ok 6 - should be equal
    ok 7 - should be equal
    ok 8 - should be equal
    ok 9 - nothing to report
ok 66 - ★ all green: relay active and in sync, PLC points here, the AppView resolves # time = 1ms

# ⛔ each failure is named, not just counted
    ok 1 - the relay has us offline
    ok 2 - the relay is behind our head, with its rev
    ok 3 - PLC points elsewhere, and where
    ok 4 - the AppView does not resolve the profile
    ok 5 - should be equal
ok 67 - ⛔ each failure is named, not just counted # time = 1ms

# a probe that throws is reported as unreachable, never thrown — metrics must always answer
    ok 1 - the relay probe failed, with the reason
    ok 2 - and that is a named problem
ok 68 - a probe that throws is reported as unreachable, never thrown — metrics must always answer # time = 0ms

# ⛔ cached: a second call within the TTL makes no request — page views must not reach bsky
    ok 1 - no new requests one minute later
    ok 2 - past the TTL it probes again
ok 69 - ⛔ cached: a second call within the TTL makes no request — page views must not reach bsky # time = 1ms

# concurrent callers share one probe in flight
    ok 1 - one getHostStatus for two simultaneous asks
ok 70 - concurrent callers share one probe in flight # time = 0ms

# ★ per DID, the last 3 posts as the AppView shows them (text kept short)
    ok 1 - should be equal
    ok 2 - should deep equal
    ok 3 - newest is still the first
ok 71 - ★ per DID, the last 3 posts as the AppView shows them (text kept short) # time = 1ms

# ★ each lens feed as bsky's getFeed returns it (top 10), or its error
    ok 1 - should be equal
    ok 2 - should be equal
    ok 3 - should be equal
    ok 4 - a feed bsky cannot load says so
    ok 5 - and it is a named problem
ok 72 - ★ each lens feed as bsky's getFeed returns it (top 10), or its error # time = 1ms

# ★ a full HTML page with bsky's view: relay, accounts, their recent posts, the feed as bsky shows it
    ok 1 - expected truthy value
    ok 2 - pds.7rnx.net
    ok 3 - active
    ok 4 - p2p.7rnx.net
    ok 5 - in sync
    ok 6 - 201 posts
    ok 7 - loser-club
    ok 8 - blursed
    ok 9 - 1 follower
    ok 10 - each post links to where bsky shows it
    ok 11 - the fediverse side links to its own timeline
ok 73 - ★ a full HTML page with bsky's view: relay, accounts, their recent posts, the feed as bsky shows it # time = 1ms

# ⛔ public means no internals: alert titles yes, commands and details no; no process stats
    ok 1 - the title of an open problem is public
    ok 2 - the fix command is not
    ok 3 - nor the detail
    ok 4 - nor process memory
ok 74 - ⛔ public means no internals: alert titles yes, commands and details no; no process stats # time = 1ms

# ⛔ post text from bsky is escaped
    ok 1 - expected falsy value
    ok 2 - expected truthy value
ok 75 - ⛔ post text from bsky is escaped # time = 0ms

# before the first probe the page still renders and says bsky has not been checked yet
    ok 1 - expected truthy value
ok 76 - before the first probe the page still renders and says bsky has not been checked yet # time = 0ms

# ★ a check opens alerts, persists them, and a new watcher (a restart) keeps "since"
    ok 1 - checks with FRESH probes, not the cache
    ok 2 - should deep equal
    ok 3 - read back from disk before any new check
    ok 4 - and kept by the next check
    ok 5 - should be equal
ok 77 - ★ a check opens alerts, persists them, and a new watcher (a restart) keeps "since" # time = 3ms

# resolved alerts are remembered (newest first, bounded) for the panel
    ok 1 - should deep equal
    ok 2 - should deep equal
ok 78 - resolved alerts are remembered (newest first, bounded) for the panel # time = 1ms

# a failing metrics call is logged and leaves the state untouched
    ok 1 - expected truthy value
    ok 2 - should deep equal
ok 79 - a failing metrics call is logged and leaves the state untouched # time = 1ms

# start() schedules the first check and the interval; stop() clears both
    ok 1 - first check plus at least one interval check (5)
    ok 2 - nothing runs after stop
ok 80 - start() schedules the first check and the interval; stop() clears both # time = 201ms

1..80
# tests = 80/80 pass
# asserts = 276/276 pass
# time = 8652ms

# ok


=== pgh publish (content-addressed -> installable app) (ok, 27101ms) ===
pgh section:
  bin: favela-gateway
    entrypoint: bin/favela-gateway.js
    upgrade: pgh://1dd36bdfa9cb7f7d84adbd07f017e7200f7f90a3a546cd0761fac2a1f8a13e86/favela-gateway
    service: port=3399 host=0.0.0.0
    type: daemon
Computing lockfile for /tmp/pear-git-ci-favela-gateway-s8DxP4...
  favela-gateway@0.6.3   root 6838629539ca
  398 top-level deps
Conflict category: production (only comparing against production apps)

pgh publish — 52 dep conflicts for favela-gateway
  51 version-split · 1 code-differs (REVIEW) · 0 docs-only · 0 noise · 0 unknown

━━ BUILD_SKEW — REVIEW: code differs under the same version (1) ━━
  autobase @ 7.28.1
      vs pear-git-v3: index.js [CODE] content, lib/apply-state.js [CODE] content

── VERSION split: independent apps on different versions (51) ──
  atproto-did-peer: favela-gateway 0.2.15  vs  favela-web 0.2.12
  atproto-identity: favela-gateway 0.0.5  vs  atproto-bridge 0.0.4, favela-web 0.0.4, favela-bridge 0.0.4
  @noble/hashes: favela-gateway 1.8.0  vs  hypernote 1.3.3
  bare-buffer: favela-gateway 3.7.1  vs  hypernote 3.4.4
  bare-channel: favela-gateway 5.2.4  vs  pear-git-v3 5.2.3, hypernote 5.2.3
  bare-crypto: favela-gateway 1.15.3  vs  hypernote 1.13.2
  bare-dns: favela-gateway 2.2.0  vs  cthuloid-web 2.2.1
  bare-format: favela-gateway 1.0.2  vs  hypernote 1.0.1
  bare-fs: favela-gateway 4.8.4  vs  hypernote 4.5.4, cthuloid-web 4.8.2
  bare-http-parser: favela-gateway 2.1.4  vs  hypernote 1.0.1
  bare-http1: favela-gateway 4.6.1  vs  hypernote 4.2.3, cthuloid-web 4.6.2
  bare-https: favela-gateway 3.1.0  vs  hypernote 2.1.2
  bare-net: favela-gateway 2.3.3  vs  hypernote 2.2.0
  bare-os: favela-gateway 3.9.3  vs  hypernote 3.6.2
  bare-pipe: favela-gateway 4.3.1  vs  hypernote 4.1.3
  bare-process: favela-gateway 4.5.1  vs  hypernote 4.2.2
  bare-semver: favela-gateway 1.1.0  vs  hypernote 1.0.2
  bare-stream: favela-gateway 2.13.4  vs  hypernote 2.8.0
  bare-structured-clone: favela-gateway 1.6.0  vs  pgh 1.5.5, pear-git-v3 1.5.5, pgh-sidecar 1.5.5, hypernote 1.5.2
  bare-subprocess: favela-gateway 6.1.0  vs  hypernote 5.2.2
  bare-tls: favela-gateway 3.1.10  vs  hypernote 2.1.7
  bare-tty: favela-gateway 5.2.1  vs  hypernote 5.0.3
  bare-url: favela-gateway 2.5.5  vs  hypernote 2.3.2
  bare-utils: favela-gateway 1.6.0  vs  hypernote 1.5.1
  bare-ws: favela-gateway 3.1.0  vs  hypernote 2.0.4
  compact-encoding: favela-gateway 3.5.2  vs  hypernote 2.19.0
  keet-identity-key: favela-gateway 3.2.0  vs  wirecore 3.1.0, hypernote 3.1.0
  paparam: favela-gateway 1.13.0  vs  hypernote 1.10.0
  picomatch: favela-gateway 4.0.7  vs  hypernote 4.0.3
  require-addon: favela-gateway 1.2.0  vs  wirecore 1.3.0
  sodium-native: favela-gateway 5.1.0  vs  hypernote 5.0.10
  streamx: favela-gateway 2.28.1  vs  hypernote 2.23.0
  atproto-store: favela-gateway 0.0.26  vs  favela-web 0.0.25, favela-bridge 0.0.25
  corestore: favela-gateway 7.12.3  vs  wirecore 6.18.4
  hypercore: favela-gateway 11.38.0  vs  wirecore 10.38.2, hypernote 11.27.17
  hypercore-storage: favela-gateway 3.2.1  vs  hypernote 2.7.1
  hyperschema: favela-gateway 1.26.2  vs  wirecore 1.24.0
  index-encoder: favela-gateway 3.5.0  vs  hypernote 3.4.0
  protomux: favela-gateway 3.11.0  vs  wirecore 3.12.0
  rocksdb-native: favela-gateway 3.17.4  vs  hypernote 3.13.0
  safety-catch: favela-gateway 1.0.3  vs  hypernote 1.0.2
  dht-rpc: favela-gateway 6.27.0  vs  hypernote 6.26.3
  hyperdht: favela-gateway 6.34.0  vs  hypernote 6.29.0
  hyperswarm: favela-gateway 4.17.0  vs  wirecore 4.17.1
  favela-identity: favela-gateway 0.0.5  vs  ap-bridge 0.0.4, atproto-bridge 0.0.4, favela-peer 0.0.4, favela-bridge 0.0.2, favela-host 0.0.4
  favela-peer: favela-gateway 0.0.64  vs  ap-bridge 0.0.63, favela-host 0.0.63
  blind-pairing-core: favela-gateway 2.10.1  vs  hypernote 2.10.0
  hyper-overlay: favela-gateway 0.3.17  vs  favela-web 0.3.13, pear-git-v3 0.3.13, blender-repo-sync 0.3.13
  bare-zlib: favela-gateway 1.4.0  vs  hypernote 1.3.1
  bare-fetch: favela-gateway 3.0.1  vs  pear-git-v3 2.8.2, hypernote 2.5.1
  bare-form-data: favela-gateway 1.2.2  vs  pear-git-v3 1.2.1, hypernote 1.1.6

⚠ 1 conflict(s) need review (code-differs / unclassified).


--accept-conflict used. Recording 52 override(s) in lockfile with reason:
  "automated CI publish; dep version-splits inherited from per-app lockfiles across the pgh ecosystem"
  ⚠ NOTE: 1 of these are code-differs — overriding a possible real build skew.
Wrote /tmp/pear-git-ci-favela-gateway-s8DxP4/.pgh-lock.json
Indexed in /home/fleeky/.config/pgh/published-index.json
Staged 1 root / 1 dep / 0 prebuild tree(s) into /home/fleeky/.local/share/store/dependencies
Appended to ReleaseRegistry via pgh-sidecar (1dd36bdfa9cb...) [signed]
published: {"name":"favela-gateway","version":"0.6.3","rootTreeHash":"6838629539caa83053e647d45bd956b00f822baa7741c1d4516e5bfbbd21708f","depCount":398,"conflicts":52,"overridden":true,"signed":true}
lockfile: /tmp/pear-git-ci-favela-gateway-s8DxP4/.pgh-lock.json
index: /home/fleeky/.config/pgh/published-index.json
registry: {"store":"/home/fleeky/.config/pgh/release-registry","keyHex":"1dd36bdfa9cb7f7d84adbd07f017e7200f7f90a3a546cd0761fac2a1f8a13e86"}
