installLogTap
Install an opt-in log tap on this device and start offering captured logs for extraction. A no-op until called — kuilt never opens a log session implicitly.
Hosts a session on loom and continuously offers exporter's log buffer for replication to any peer that joins. The tap is fabric-agnostic: pass a loopback WebSocket Loom for a simulator/CI puller (the default and safest choice — it binds only the local loopback interface), or a LAN/peer-to-peer Loom to reach a real device. Discovery and admission are the Loom's concern, not the tap's.
Parameters
the fabric to host the session on. Bind it to loopback by default.
the device's captured-log buffer to offer.
the scope the host's replicator runs in. Closing the returned host (or cancelling this scope) stops the tap.
tap tuning; the defaults suit a developer turning the tap on to debug.
how peers are admitted. The default LogTapAdmission.Open keeps the loopback-safe ungated behaviour; pass LogTapAdmission.Verify to require a join code before a peer can pull (see installLogTapJoining for the device-joins topology).
Samples
// The device's captured-log buffer — the same one installLogCapture fills.
val exporter = WarpLogRecordExporter(
replica = ReplicaId("device-uuid-abc123"),
store = InMemoryDurableStore(),
)
// The fabric the two peers meet over. An in-memory/loopback Loom is the
// simulator-and-CI case; swap it for a LAN (mDNS + WebSocket) or peer-to-peer
// (Multipeer) Loom to reach a real phone — the tap code below is unchanged.
val loom = InMemoryLoom()
// On the device: turn the opt-in tap on. It does nothing until called and is
// loopback-bound by default. Hold the host; close it to stop offering logs.
val host = installLogTap(loom, exporter, scope)
// In the test / CI harness: join the same session and pull the backlog —
// every line the device captured, in the device's order, with no duplicates.
val client = LogTapClient(loom.join(InMemoryTag("puller")), scope)
val logs: List<LogRecord> = client.pull()
// Release both replicators when finished.
client.close()
host.close()
return logs