//! mgf-hrb `format` (wire layer) — request → response formatters + the
//! JSON response machinery, extracted from `server.zig` (1A-ii of the
//! SOLID redesign). Each `fmt*` is a PURE function of (facade,
//! request-fields, out buffer) returning the response-line bytes; the
//! transport shell (`server.zig`) wraps the result in a `DispatchResult`
//! and writes it. The `*Collector` / `*Writer` structs are the per-op JSON
//! serialisers; `fmtErr` + `errToWireCode` are the typed error envelope.
//! No connection/socket/admission state lives here — this layer only turns
//! a validated request into response bytes.

const std = @import("std");
const model = @import("mgf_hrb_model");
const kabi = @import("mgf_hrb_kabi");
const cap = @import("mgf_hrb_cap");
const core_mod = @import("mgf_hrb_core");
const Core = core_mod.Core;
const facademod = @import("mgf_hrb_facade");
const request = @import("mgf_hrb_request");
const audit = @import("mgf_hrb_audit");
const subscription = @import("mgf_hrb_subscription");
const driver_registry = @import("mgf_hrb_driver_registry");
const irqmod = @import("mgf_hrb_irq_monitor");
const lbound = @import("mgf_hrb_linux_bound");

const Urn = model.Urn;
const Err = model.Err;
const Deadline = kabi.Deadline;
const linux = std.os.linux;

/// Translate a client-supplied `deadline_ms` (0 = absent) into a `Deadline`.
/// Used by the write-op formatters (revoke/recover) and by the dispatcher.
pub fn deadlineFrom(ms: u64) Deadline {
    return if (ms == 0) Deadline.none else Deadline.fromNow(ms);
}

// ===========================================================================
// Extracted verbatim from server.zig (1A-ii). Behaviour unchanged — pinned
// by the wire contract suite (every op end-to-end).
// ===========================================================================

pub fn fmtListLeases(facade: *facademod.Facade, scope: []const u8, cap_id: u64, out: []u8) []const u8 {
    const prefix = "{\"ok\":true,\"leases\":[";
    @memcpy(out[0..prefix.len], prefix);
    var writer = LeaseJsonWriter{ .out = out, .pos = prefix.len, .cap = out.len - ENUM_TAIL_MARGIN };
    // R-T1-11B — wire the cap filter when the cap layer is enforced AND
    // the request presented a cap_id. cap_id == 0 (default / legacy
    // clients) bypasses the filter. Same S3-isolation shape as `list`:
    // lease records whose URN is outside the cap's scope are dropped.
    if (facade.usesCapFilter(cap_id)) {
        writer.facade_for_filter = facade;
        writer.cap_id = cap_id;
    }
    const sink = core_mod.LeaseSink{ .ctx = &writer, .push = LeaseJsonWriter.push };
    facade.listLeases(scope, &sink);
    // R-T1-9E — bounded, honest tail (reserved margin guarantees it fits).
    const tail = std.fmt.bufPrint(out[writer.pos..], "],\"truncated\":{}}}\n", .{writer.truncated}) catch "]}\n";
    return out[0 .. writer.pos + tail.len];
}

/// Sink that serializes LeaseRecords as JSON objects into a
/// comma-separated list (no enclosing braces — caller wraps). Each
/// record becomes one `{"urn":"...","lease_id":N,"mode":"...","holder":N,"granted_at_ms":N}`.
const LeaseJsonWriter = struct {
    out: []u8,
    pos: usize,
    count: usize = 0,
    /// R-T1-9E — emission ceiling (out.len − ENUM_TAIL_MARGIN) + honest
    /// truncation flag, same shape as `ListCollector`.
    cap: usize = 0,
    truncated: bool = false,
    /// R-T1-11B — when non-null, lease records are filtered by this
    /// cap_id: only URNs the cap permits naming are emitted. Set by
    /// `fmtListLeases` when the request carries `cap_id != 0` and the
    /// verifier is wired. null preserves legacy behavior.
    facade_for_filter: ?*facademod.Facade = null,
    cap_id: u64 = 0,

    fn push(ctx: *anyopaque, r: core_mod.LeaseRecord) void {
        const self: *LeaseJsonWriter = @ptrCast(@alignCast(ctx));
        if (self.truncated) return;
        // R-T1-11B — filter by cap scope BEFORE emission. A holder of an
        // attenuated cap must not observe the existence of leases on
        // resources outside its grant (S3 isolation, U11).
        if (self.facade_for_filter) |f| {
            if (!f.capPermitsNaming(self.cap_id, &r.urn)) return;
        }
        const sep = if (self.count == 0) "" else ",";
        // R-T1-9E — bound to `cap` (tail margin reserved); on overflow set
        // truncated honestly rather than silently dropping records.
        const w = std.fmt.bufPrint(
            self.out[self.pos..self.cap],
            "{s}{{\"urn\":\"{s}\",\"lease_id\":{d},\"mode\":\"{s}\",\"holder\":{d},\"granted_at_ms\":{d}}}",
            .{
                sep,
                r.urn.slice(),
                r.lease_id,
                @tagName(r.mode),
                r.holder,
                r.granted_at_ms,
            },
        ) catch {
            self.truncated = true;
            return;
        };
        self.pos += w.len;
        self.count += 1;
    }
};

/// `revoke` op response (Tier-0 #4 / survivability §3.4).
/// Cap-gated by the `steal` right (taking a device AWAY from
/// another holder is a stricter authority than `claim`). The
/// formatter does the verifier check; the facade does the
/// (backend.revoke + Core.markRevokedByUrn) two-step.
///
/// Success response: `{ok:true}`. The teardown is "tear down +
/// mark revoked"; no payload to return.
pub fn fmtRevoke(
    facade: *facademod.Facade,
    peer: cap.PeerCred,
    r: *const request.RevokeReq,
    out: []u8,
) []const u8 {
    if (facade.verifier) |ct| {
        if (!ct.permitsRevokeFromPeer(r.cap_id, &r.urn, peer)) {
            return fmtErr(out, "NotPermitted");
        }
    }
    facade.revoke(&r.urn, deadlineFrom(r.deadline_ms)) catch |e|
        return fmtErr(out, errToWireCode(e));
    return std.fmt.bufPrint(out, "{{\"ok\":true}}\n", .{}) catch fmtErr(out, "fmt");
}

/// `attenuate` op response (R-CAP-ATTEN-WIRE). Mints a strictly-weaker
/// sub-capability from the connection's cap (`r.cap_id` is the parent)
/// and returns its CSPRNG-drawn id. `CapTable.attenuateFromPeer` enforces
/// the three authority checks: the parent must carry the `grant` right,
/// the connection `peer` must match the parent's binding, and every
/// narrowing can only SHRINK authority (a widen is refused) — so this
/// op can never escalate. Success: `{"ok":true,"cap_id":<sub_cap_id>}`.
/// Refusals surface as `NotPermitted` (missing parent / no grant / wrong
/// peer / attempted widen) or `Overloaded` (cap-table OOM).
pub fn fmtAttenuate(
    facade: *facademod.Facade,
    peer: cap.PeerCred,
    r: *const request.AttenuateReq,
    out: []u8,
) []const u8 {
    const ct = facade.verifier orelse return fmtErr(out, "NotPermitted");
    const sub_id = ct.attenuateFromPeer(r.cap_id, peer, r.restriction()) catch |e|
        return fmtErr(out, errToWireCode(e));
    return std.fmt.bufPrint(out, "{{\"ok\":true,\"cap_id\":{d}}}\n", .{sub_id}) catch fmtErr(out, "fmt");
}

/// `recover` op response (Tier-1 #12). Runs the reset-escalation ladder
/// on a quarantined URN to bring it back to `Free`. `steal`-right gated —
/// the same forceful-hardware authority as `revoke` (recovery resets a
/// device; only an operator-class cap should). The ladder always
/// terminates (each rung is deadline-bounded + abandonable), so this
/// never errors past the cap check; the outcome is reported as a string:
/// `not_quarantined` (no-op — the URN was healthy), `recovered_flr` /
/// `recovered_bus` (back to Free), or `still_quarantined` (both rungs
/// failed; the device needs power-cycle / operator intervention).
pub fn fmtRecover(
    facade: *facademod.Facade,
    peer: cap.PeerCred,
    r: *const request.RecoverReq,
    out: []u8,
) []const u8 {
    if (facade.verifier) |ct| {
        if (!ct.permitsRevokeFromPeer(r.cap_id, &r.urn, peer)) {
            return fmtErr(out, "NotPermitted");
        }
    }
    const outcome = facade.recoverByReset(&r.urn, deadlineFrom(r.deadline_ms));
    const name = switch (outcome) {
        .not_quarantined => "not_quarantined",
        .recovered_flr => "recovered_flr",
        .recovered_bus => "recovered_bus",
        .still_quarantined => "still_quarantined",
    };
    return std.fmt.bufPrint(out, "{{\"ok\":true,\"outcome\":\"{s}\"}}\n", .{name}) catch fmtErr(out, "fmt");
}

/// `reconcile` op (Tier-1 #8, R-T1-8-RESTART-WIRING) — the broker-wide restart
/// recovery trigger. Steal-gated on the requested scope (reusing the same
/// `permitsRevokeFromPeer` check as `recover`, so only a cap with authority over
/// `scope` can reconcile it — a narrow sub-cap can't quarantine a namespace it
/// doesn't own). Returns `{quarantined, scanned, truncated}`. MUST be triggered
/// only after an actual restart (see `Facade.reconcileAfterRestart`) — run on a
/// healthy broker it would quarantine every idle device; the steal-gate keeps
/// that power to an operator/supervisor cap.
pub fn fmtReconcile(
    facade: *facademod.Facade,
    peer: cap.PeerCred,
    r: *const request.ReconcileReq,
    out: []u8,
) []const u8 {
    if (facade.verifier) |ct| {
        if (!ct.permitsRevokeFromPeer(r.cap_id, &r.scope, peer)) {
            return fmtErr(out, "NotPermitted");
        }
    }
    // R-T1-8 (b) — feed reconcile the real bound-classification source so it
    // only quarantines genuinely hardware-bound orphans (vfio-pci PCI; non-PCI
    // stays conservatively included), not idle-free / host-used devices.
    const report = facade.reconcileAfterRestart(r.scope.slice(), lbound.boundSource(), deadlineFrom(r.deadline_ms));
    return std.fmt.bufPrint(
        out,
        "{{\"ok\":true,\"quarantined\":{d},\"scanned\":{d},\"truncated\":{s}}}\n",
        .{ report.quarantined, report.scanned, if (report.truncated) "true" else "false" },
    ) catch fmtErr(out, "fmt");
}

/// `irq_scan` op (D7, Tier-2) — the operator/supervisor trigger for the
/// interrupt-rate containment hook. Steal-gated on `hw:/**` (the same
/// operator-class authority as `reconcile`/`recover`; a stranger can't sweep the
/// whole namespace). Samples every granted device via the broker-wide monitor +
/// counter source and revoke+quarantines any flooder. Returns
/// `{scanned, contained}`. Cold path — never on the hot use path.
pub fn fmtIrqScan(
    facade: *facademod.Facade,
    peer: cap.PeerCred,
    r: *const request.IrqScanReq,
    out: []u8,
) []const u8 {
    if (facade.verifier) |ct| {
        if (!ct.permitsRevokeFromPeer(r.cap_id, &Urn.from("hw:/**"), peer)) {
            return fmtErr(out, "NotPermitted");
        }
    }
    const report = facade.scanInterruptRates(
        irqmod.globalMonitor(),
        irqmod.globalSource(),
        kabi.nowMs(),
        deadlineFrom(r.deadline_ms),
    );
    return std.fmt.bufPrint(
        out,
        "{{\"ok\":true,\"scanned\":{d},\"contained\":{d}}}\n",
        .{ report.scanned, report.contained },
    ) catch fmtErr(out, "fmt");
}

/// `control` op response with Part 13 §5.1.2 disclosure shape
/// (sub-phase 4B). Dispatches the typed verb to the owning worker;
/// the backend's serialiser (sub-phase 4A) FIFO-orders concurrent
/// writers per (urn, verb) and returns a typed `ControlOutcome`
/// the writer learns:
///   * `generation` — monotonic per (urn, verb).
///   * `applied_value` — what landed (verifies the write).
///   * `queue_depth` — how many writers were behind ours.
///   * `superseded_by` — non-null when another writer landed
///     between our unlock and this response emit. `null` today
///     (the in-broker path doesn't yet re-snapshot post-unlock —
///     see the implementation note in linux_usb.vControl).
pub fn fmtControl(facade: *facademod.Facade, r: *const request.ControlReq, out: []u8) []const u8 {
    const outcome = facade.control(
        &r.urn,
        r.verb,
        r.value(),
        r.cap_id,
        Deadline.fromNow(5_000),
    ) catch |e| return fmtErr(out, errToWireCode(e));

    // The applied_value is bounded by kabi.MAX_CONTROL_VALUE_BYTES;
    // its content is the wire-supplied value, which was charset-
    // validated only as "fits in the buffer" at the gate. To be
    // safe in JSON, we restrict the emit to printable ASCII and
    // skip past anything weirder by treating the response field as
    // an opaque echo. Today's verb values are short ASCII tokens
    // (e.g. "1", "auto", "usbhid") — non-trivial bytes never reach
    // here. JSON-escape only the two characters that NEVER appear
    // in legitimate control values but COULD in a malformed
    // payload (the broker has already rejected those at the gate
    // via the value-len cap; defense in depth still escapes).
    if (outcome.superseded_by) |sb| {
        return std.fmt.bufPrint(
            out,
            "{{\"ok\":true,\"generation\":{d}" ++
                ",\"applied_value\":\"{s}\"" ++
                ",\"queue_depth\":{d}" ++
                ",\"superseded_by\":{{\"generation\":{d}" ++
                ",\"cap_id\":{d},\"at_ms\":{d}}}}}\n",
            .{
                outcome.generation,
                outcome.appliedValue(),
                outcome.queue_depth,
                sb.generation,
                sb.cap_id,
                sb.at_ms,
            },
        ) catch fmtErr(out, "fmt");
    }
    return std.fmt.bufPrint(
        out,
        "{{\"ok\":true,\"generation\":{d}" ++
            ",\"applied_value\":\"{s}\"" ++
            ",\"queue_depth\":{d}" ++
            ",\"superseded_by\":null}}\n",
        .{ outcome.generation, outcome.appliedValue(), outcome.queue_depth },
    ) catch fmtErr(out, "fmt");
}

/// `drain_events` op response. Two modes (Part 13 §5.4.2):
///
///   * **Subscriber mode** — request carries `subscription_id`. The
///     dispatcher drains from THAT subscription's bounded queue
///     (events already filtered by the subscription's predicate).
///     `scope` on the request is ignored; the subscription's stored
///     scope was used at fan-out time.
///   * **Legacy mode** — no `subscription_id`. The dispatcher pulls
///     every backend-buffered event whose worker scope intersects
///     `scope`, fans them out to every active subscription's queue
///     (for background filtering), and returns the raw stream.
///
/// In both modes the response shape is `{ok:true,events:[...]}`.
/// Honest emptiness: returns `[]` when no events are available.
pub fn fmtDrainEvents(
    facade: *facademod.Facade,
    peer_key: u64,
    r: *const request.DrainEventsReq,
    out: []u8,
) []const u8 {
    const prefix = "{\"ok\":true,\"events\":[";
    @memcpy(out[0..prefix.len], prefix);
    var writer = EventJsonWriter{ .out = out, .pos = prefix.len };

    if (r.hasSubscriptionId()) {
        // Pull what the backends have buffered, fanning out to every
        // active subscription (so concurrent subscribers get their
        // share), then drain this caller's subscription queue and
        // write THOSE events to the response.
        const fanout_sink = kabi.EventSink{
            .ctx = undefined,
            .push = fanoutPush,
        };
        facade.drainEvents(r.scope.slice(), &fanout_sink, Deadline.fromNow(5_000)) catch {};

        // Drain the caller's subscription. Cap at the response
        // buffer's ~MAX_QUEUE_LEN; oversized batches would overflow
        // the response anyway.
        var buf: [subscription.MAX_QUEUE_LEN]model.Event = undefined;
        const n = subscription.drainSubscription(
            peer_key,
            r.subscriptionId(),
            &buf,
        ) catch |e| return fmtErr(out, errToWireCode(e));
        for (buf[0..n]) |ev| EventJsonWriter.push(&writer, ev);
    } else {
        // Legacy mode. Tee: the writer captures events into the
        // response buffer, AND each event also fans out to every
        // active subscription's queue. A small wrapper sink does
        // both in one push.
        var tee = TeeSink{ .out_writer = &writer };
        const sink = kabi.EventSink{ .ctx = &tee, .push = TeeSink.push };
        facade.drainEvents(r.scope.slice(), &sink, Deadline.fromNow(5_000)) catch {};
    }

    const suffix = "]}\n";
    @memcpy(out[writer.pos..][0..suffix.len], suffix);
    return out[0 .. writer.pos + suffix.len];
}

/// Sink wrapper that pushes each event to BOTH the response writer
/// AND the subscription registry's fan-out. Used by drain_events
/// legacy mode so subscribers see events even when no one is in
/// subscriber-mode drain.
const TeeSink = struct {
    out_writer: *EventJsonWriter,

    fn push(ctx: *anyopaque, ev: model.Event) void {
        const self: *TeeSink = @ptrCast(@alignCast(ctx));
        EventJsonWriter.push(self.out_writer, ev);
        subscription.pushFanout(ev, .{ .ctx = null, .get = null });
    }
};

/// Sink callback for subscriber-mode fan-out: pushes to subscriptions
/// only (the caller's events are drained separately from the queue).
/// `_ = ctx`: this sink carries no state. The attribute lookup is
/// null in v1 — device-attr predicate evaluation against intrinsic
/// fields only; the inspect-on-event escape hatch is wired in a
/// follow-up commit once a perf-aware cache lands.
fn fanoutPush(ctx: *anyopaque, ev: model.Event) void {
    _ = ctx;
    subscription.pushFanout(ev, .{ .ctx = null, .get = null });
}

/// `subscribe` op response (Part 13 §5.4.2). Re-parses the original
/// request line to extract the `predicate` sub-object (when the
/// gate flagged its presence), builds the predicate AST inside a
/// fresh per-subscription arena, and registers the subscription
/// under the peer's cap_id. Response carries the echoed
/// subscription id + the bounded queue size.
pub fn fmtSubscribe(
    peer_key: u64,
    r: *const request.SubscribeReq,
    line: []const u8,
    out: []u8,
) []const u8 {
    // Build the predicate AST inside a per-subscription arena.
    // ArenaAllocator's child allocator is page_allocator — same
    // pattern as request.parse uses for its transient std.json
    // allocations.
    var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
    var predicate: subscription.Predicate = .{ .matches_all = {} };

    if (r.has_predicate) {
        // Re-parse the line to fish out the predicate sub-value.
        // Use a separate allocator for this transient parse so the
        // subscription's own arena only holds the AST.
        var json_arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
        defer json_arena.deinit();
        const parsed = std.json.parseFromSlice(
            std.json.Value,
            json_arena.allocator(),
            line,
            .{},
        ) catch {
            arena.deinit();
            return fmtErr(out, "BadRequest");
        };
        defer parsed.deinit();
        const root = switch (parsed.value) {
            .object => |o| o,
            else => {
                arena.deinit();
                return fmtErr(out, "BadRequest");
            },
        };
        const pred_v = root.get("predicate") orelse {
            // Inconsistent with the gate flag — treat as BadRequest.
            arena.deinit();
            return fmtErr(out, "BadRequest");
        };
        var node_budget: u32 = subscription.MAX_PREDICATE_NODES;
        predicate = subscription.parsePredicate(
            pred_v,
            arena.allocator(),
            &node_budget,
        ) catch |e| {
            arena.deinit();
            return fmtErr(out, errToWireCode(e));
        };
    }

    // Hand the arena+predicate to the registry. On success, the
    // registry takes ownership; on failure, register() drains the
    // arena itself.
    _ = subscription.register(
        peer_key,
        r.id(),
        r.scope.slice(),
        predicate,
        arena,
    ) catch |e| return fmtErr(out, errToWireCode(e));

    return std.fmt.bufPrint(
        out,
        "{{\"ok\":true,\"subscription_id\":\"{s}\",\"queue_max\":{d}}}\n",
        .{ r.id(), subscription.MAX_QUEUE_LEN },
    ) catch fmtErr(out, "fmt");
}

/// `unsubscribe` op response (Part 13 §5.4.2). Tears down the named
/// subscription owned by the calling peer. Returns NotFound when no
/// such subscription exists — idempotency is the caller's job.
pub fn fmtUnsubscribe(
    peer_key: u64,
    r: *const request.UnsubscribeReq,
    out: []u8,
) []const u8 {
    subscription.unregister(peer_key, r.id()) catch |e|
        return fmtErr(out, errToWireCode(e));
    return std.fmt.bufPrint(out, "{{\"ok\":true}}\n", .{}) catch fmtErr(out, "fmt");
}

/// Sink that serializes Events as JSON objects into a comma-separated
/// list (no enclosing braces — caller wraps). Each event becomes one
/// `{"kind":"added","urn":"..."}` style object.
const EventJsonWriter = struct {
    out: []u8,
    pos: usize,
    count: usize = 0,

    fn push(ctx: *anyopaque, ev: model.Event) void {
        const self: *EventJsonWriter = @ptrCast(@alignCast(ctx));
        const sep = if (self.count == 0) "" else ",";
        const w = switch (ev) {
            .added => |a| std.fmt.bufPrint(
                self.out[self.pos..],
                "{s}{{\"kind\":\"added\",\"urn\":\"{s}\"}}",
                .{ sep, a.urn.slice() },
            ) catch return,
            .removed => |r| std.fmt.bufPrint(
                self.out[self.pos..],
                "{s}{{\"kind\":\"removed\",\"urn\":\"{s}\"}}",
                .{ sep, r.urn.slice() },
            ) catch return,
            .gap => |g| std.fmt.bufPrint(
                self.out[self.pos..],
                "{s}{{\"kind\":\"gap\",\"source\":\"{s}\",\"since_ms\":{d}}}",
                .{ sep, @tagName(g.source), g.since_ms },
            ) catch return,
            // The watch synthesizer (`usb_synth.zig`, Part 5.3.4) collapses
            // remove+add pairs whose snapshots agree at `Confidence.likely_same`
            // or stronger into a single `state_changed` carrying the previous
            // URN. We surface `previous_urn` as an optional field — consumers
            // that only care about the new URN can ignore it; smart consumers
            // can correlate against their prior view.
            .state_changed => |sc| if (sc.previous_urn) |prev| std.fmt.bufPrint(
                self.out[self.pos..],
                "{s}{{\"kind\":\"state_changed\",\"urn\":\"{s}\",\"old\":\"{s}\",\"new\":\"{s}\",\"previous_urn\":\"{s}\"}}",
                .{ sep, sc.urn.slice(), @tagName(sc.old), @tagName(sc.new), prev.slice() },
            ) catch return else std.fmt.bufPrint(
                self.out[self.pos..],
                "{s}{{\"kind\":\"state_changed\",\"urn\":\"{s}\",\"old\":\"{s}\",\"new\":\"{s}\"}}",
                .{ sep, sc.urn.slice(), @tagName(sc.old), @tagName(sc.new) },
            ) catch return,
            // Part 13 §5.4.1 — driver lifecycle from netlink uevents.
            // Carries the URN (so consumers can correlate with `inspect`)
            // plus the kernel driver name (e.g. "usbhid", "uvcvideo").
            .driver_bound => |b| std.fmt.bufPrint(
                self.out[self.pos..],
                "{s}{{\"kind\":\"driver_bound\",\"urn\":\"{s}\",\"driver\":\"{s}\"}}",
                .{ sep, b.urn.slice(), b.driver.slice() },
            ) catch return,
            .driver_unbound => |u| std.fmt.bufPrint(
                self.out[self.pos..],
                "{s}{{\"kind\":\"driver_unbound\",\"urn\":\"{s}\",\"driver\":\"{s}\"}}",
                .{ sep, u.urn.slice(), u.driver.slice() },
            ) catch return,
            else => std.fmt.bufPrint(
                self.out[self.pos..],
                "{s}{{\"kind\":\"other\"}}",
                .{sep},
            ) catch return,
        };
        self.pos += w.len;
        self.count += 1;
    }
};

/// `inspect` op response. Wraps the basic `Resource` + a JSON object of
/// backend-pushed attributes (USB: vid/pid/serial/class/...; PCI:
/// vendor/device/class/bdf/...). The shape is open by design so each
/// backend reports what's natural for its substrate without a closed
/// schema (USB-worker §5.9).
pub fn fmtInspect(facade: *facademod.Facade, urn: *const model.Urn, cap_id: u64, out: []u8) []const u8 {
    // R-T1-11D — capability-filtered enumeration for the single-URN
    // inspect. When the cap filter applies and the URN is outside the
    // cap's scope, return NotFound — the holder of an attenuated cap
    // can't distinguish an out-of-scope URN from a nonexistent one
    // (existence isn't observable beyond the grant, U11). Same shape
    // as `fmtInspectFull`.
    if (facade.usesCapFilter(cap_id) and !facade.capPermitsNaming(cap_id, urn)) {
        return fmtErr(out, "NotFound");
    }
    // Build the attrs section into a side buffer while the inspect call
    // runs, then assemble the full response with the Resource fields.
    var attrs_buf: [4096]u8 = undefined;
    var attrs_writer = AttrJsonWriter{ .out = &attrs_buf };
    const sink = kabi.AttrSink{ .ctx = &attrs_writer, .push = AttrJsonWriter.push };

    const res = facade.inspect(urn, &sink, Deadline.fromNow(5_000)) catch |e|
        return fmtErr(out, errToWireCode(e));

    const written = std.fmt.bufPrint(
        out,
        "{{\"ok\":true,\"resource\":{{" ++
            "\"urn\":\"{s}\"" ++
            ",\"family\":\"{s}\"" ++
            ",\"kind\":\"{s}\"" ++
            ",\"fidelity\":\"{s}\"" ++
            ",\"attrs\":{{{s}}}" ++
            "}}}}\n",
        .{
            res.urn.slice(),
            @tagName(res.family),
            @tagName(res.kind),
            @tagName(res.fidelity),
            attrs_writer.slice(),
        },
    ) catch fmtErr(out, "fmt");
    return written;
}

/// Sink that serializes attrs into a JSON-object body (no enclosing
/// braces — the caller wraps). Safe across multiple pushes per inspect.
/// G2 (review wave 2) — JSON-string escape helper lives in its own
/// module so it can be unit-tested under `zig build test` (server.zig
/// itself is built as an executable, not a test target). See
/// `json_escape.zig` for the full rationale + the per-case tests.
const json_escape = @import("mgf_hrb_json_escape");
const appendJsonEscaped = json_escape.appendEscaped;

const AttrJsonWriter = struct {
    out: []u8,
    pos: usize = 0,
    count: usize = 0,

    fn push(ctx: *anyopaque, a: kabi.Attr) void {
        const self: *AttrJsonWriter = @ptrCast(@alignCast(ctx));
        const sep = if (self.count == 0) "" else ",";
        // G2 — write each piece with JSON-escape on the values that
        // come from the backend (the key is broker-curated and safe
        // to splice verbatim; the value is substrate-controlled and
        // could legitimately contain `"` / `\` / control bytes).
        // Layout: `<sep>"<key>":"<escaped-value>"`. If any piece
        // would overflow `out`, we silently bail without committing —
        // the unattached partial doesn't corrupt earlier attrs (pos
        // hasn't moved). Truncation semantics for the response as
        // whole are handled by the formatter's outer buffer.
        var p = self.pos;
        // separator
        if (p + sep.len > self.out.len) return;
        @memcpy(self.out[p..][0..sep.len], sep);
        p += sep.len;
        // key: "<key>"
        if (p + 1 > self.out.len) return;
        self.out[p] = '"';
        p += 1;
        p = appendJsonEscaped(self.out, p, a.key) orelse return;
        if (p + 3 > self.out.len) return;
        @memcpy(self.out[p..][0..3], "\":\"");
        p += 3;
        // value
        p = appendJsonEscaped(self.out, p, a.value) orelse return;
        if (p + 1 > self.out.len) return;
        self.out[p] = '"';
        p += 1;
        // commit
        self.pos = p;
        self.count += 1;
    }

    fn slice(self: *const AttrJsonWriter) []const u8 {
        return self.out[0..self.pos];
    }
};

/// R-T1-9E — tail margin reserved in enumeration buffers for the closing
/// `],"truncated":<bool>}\n`. The longest tail is `],"truncated":false}\n`
/// (21 bytes); 32 is comfortable headroom. Emission stops before this
/// margin so (a) the tail always fits — no suffix-write overflow — and
/// (b) when more results existed than fit, we say so honestly.
const ENUM_TAIL_MARGIN: usize = 32;

const ListCollector = struct {
    out: []u8,
    pos: usize = 0,
    count: usize = 0,
    /// R-T1-9E — emission ceiling (out.len − ENUM_TAIL_MARGIN). Writes
    /// stop here so the closing `truncated` tail always fits.
    cap: usize = 0,
    /// R-T1-9E — set true when at least one result didn't fit. The wire
    /// signal that the consumer should re-issue against a narrower scope
    /// (honest bound, matching `dump_all` / `inspect_full`).
    truncated: bool = false,
    /// R-T1-11A — when non-null, results are filtered by this cap_id:
    /// only URNs the cap permits naming are emitted. Set by `fmtList`
    /// when the request carries a `cap_id != 0` and the verifier is
    /// wired. null preserves legacy behavior (emit every URN).
    facade_for_filter: ?*facademod.Facade = null,
    cap_id: u64 = 0,
    fn push(ctx: *anyopaque, r: model.Resource) void {
        const self: *ListCollector = @ptrCast(@alignCast(ctx));
        // Once truncated, stop — don't keep probing for smaller URNs that
        // might still squeeze in (that would emit an out-of-order subset).
        if (self.truncated) return;
        // R-T1-11A — filter by cap scope BEFORE emission. The cap layer
        // is the authority; URNs outside the cap's scope are not emitted
        // (the caller can't even *observe the existence* of resources
        // beyond its grant — that's the U11 isolation property).
        if (self.facade_for_filter) |f| {
            if (!f.capPermitsNaming(self.cap_id, &r.urn)) return;
        }
        const sep = if (self.count == 0) "" else ",";
        // R-T1-9E — bound the write to `cap` (leaving the tail margin).
        // On overflow, mark truncated honestly instead of silently
        // dropping the URN (and never write past the buffer).
        const w = std.fmt.bufPrint(self.out[self.pos..self.cap], "{s}\"{s}\"", .{ sep, r.urn.slice() }) catch {
            self.truncated = true;
            return;
        };
        self.pos += w.len;
        self.count += 1;
    }
};

pub fn fmtList(
    facade: *facademod.Facade,
    scope: []const u8,
    cap_id: u64,
    out: []u8,
) []const u8 {
    // build: {"ok":true,"resources":[...],"truncated":<bool>}
    const prefix = "{\"ok\":true,\"resources\":[";
    @memcpy(out[0..prefix.len], prefix);
    var col = ListCollector{ .out = out, .pos = prefix.len, .cap = out.len - ENUM_TAIL_MARGIN };
    // R-T1-11A — wire the cap filter when the cap layer is enforced AND
    // the request presented a cap_id. cap_id == 0 (default / legacy
    // clients) bypasses the filter to preserve backward compatibility
    // for SDK versions that don't yet carry cap_id on list().
    if (facade.usesCapFilter(cap_id)) {
        col.facade_for_filter = facade;
        col.cap_id = cap_id;
    }
    const sink = kabi.FactSink{ .ctx = &col, .push = ListCollector.push };
    // The list/enumerate op doesn't yet carry a client-supplied deadline in
    // the wire format (it's an Observer-class read; cheap). Default budget:
    // a generous one so a flood of devices on slow sysfs doesn't surprise-
    // truncate. The future SDK list() call should accept and forward one.
    facade.enumerate(scope, &sink, Deadline.fromNow(5000)) catch {};
    // R-T1-9E — bounded tail write (the reserved margin guarantees it
    // fits; no more @memcpy-past-the-end on a full buffer).
    const tail = std.fmt.bufPrint(out[col.pos..], "],\"truncated\":{}}}\n", .{col.truncated}) catch "]}\n";
    return out[0 .. col.pos + tail.len];
}

pub fn fmtErr(out: []u8, msg: []const u8) []const u8 {
    return std.fmt.bufPrint(out, "{{\"ok\":false,\"err\":\"{s}\"}}\n", .{msg}) catch "{\"ok\":false}\n";
}

/// J2 (review wave 2 — Cluster J): exhaustive Err → wire code mapping.
///
/// Replaces the previous `@errorName(e)` pattern at every callsite
/// (search: `fmtErr(out, errToWireCode(e))`). The point: when a future
/// contributor adds a new `Err.X` variant to `model.zig`, Zig's
/// exhaustiveness checker compile-fails the switch below UNLESS the
/// new variant is explicitly mapped. That closes a real leakage
/// class — pre-J2 a new internal error would propagate to the wire
/// as its raw Zig name (e.g. `"VfioMappingExhausted"`), which the
/// SDK's `from_wire` would translate to a generic
/// `MgfHrbError(<unknown_code>)` and the consumer would never know
/// the broker grew an undocumented failure mode.
///
/// The strings emitted here ARE the wire contract — the SDK's
/// `from_wire` in `src/mgf/hrb/exceptions.py` matches on each.
/// Adding a new mapping = pinning a new wire-code; never rename
/// without a wire-breaking ledger entry.
pub fn errToWireCode(e: Err) []const u8 {
    return switch (e) {
        Err.NotFound => "NotFound",
        Err.NotPermitted => "NotPermitted",
        Err.Conflict => "Conflict",
        Err.Unsupported => "Unsupported",
        Err.HardwareFault => "HardwareFault",
        Err.InvalidToken => "InvalidToken",
        Err.BadRequest => "BadRequest",
        Err.Timeout => "Timeout",
        Err.Overloaded => "Overloaded",
        Err.Revoked => "Revoked",
        Err.Unavailable => "Unavailable",
    };
}

/// Two-pass collector for `dump_all`. Pass 1: enumerate URNs into a
/// fixed-size side buffer. Pass 2: per URN, call inspect and emit the
/// assembled resource + attrs into `out`. The fixed cap (128 URNs) is
/// the budget for one response on a typical hardware host; scopes
/// matching more return truncated honestly so consumers can re-issue
/// against a narrower scope (G2 — never silently drop data).
const DumpAllCollector = struct {
    urns: [128]model.Urn = undefined,
    count: usize = 0,
    overflowed: bool = false,
    /// R-T1-11B — when non-null, URNs are filtered by this cap_id during
    /// pass-1 enumeration: out-of-scope URNs never enter the side buffer,
    /// so they're never inspected in pass 2 nor emitted. Set by
    /// `fmtDumpAll` when the request carries `cap_id != 0` and the
    /// verifier is wired. null preserves legacy behavior.
    facade_for_filter: ?*facademod.Facade = null,
    cap_id: u64 = 0,

    fn push(ctx: *anyopaque, r: model.Resource) void {
        const self: *DumpAllCollector = @ptrCast(@alignCast(ctx));
        // R-T1-11B — filter by cap scope BEFORE the URN enters the
        // buffer. A holder of an attenuated cap must not observe the
        // existence of resources outside its grant (S3 isolation, U11).
        if (self.facade_for_filter) |f| {
            if (!f.capPermitsNaming(self.cap_id, &r.urn)) return;
        }
        if (self.count >= self.urns.len) {
            self.overflowed = true;
            return;
        }
        self.urns[self.count] = r.urn;
        self.count += 1;
    }
};

/// `dump_all` op response (Part 13 §5.5.3). Walks every URN in scope,
/// calls inspect per URN, returns the assembled set.
///
///     {"ok":true,"scope":"hw:/usb/**","items":[
///       {"urn":"...","family":"...","kind":"...","fidelity":"...","attrs":{...}},
///       ...
///     ],"count":N,"truncated":false}
///
/// Honest emptiness: a scope matching no URNs → `items: []`, `count: 0`.
/// Honest truncation: a scope matching more URNs than fit in the
/// response buffer → emit what fits, set `truncated: true`. Consumers
/// can re-issue against a narrower scope.
pub fn fmtDumpAll(facade: *facademod.Facade, scope: []const u8, cap_id: u64, out: []u8) []const u8 {
    // Pass 1: enumerate URNs into the side buffer.
    var col = DumpAllCollector{};
    // R-T1-11B — wire the cap filter when the cap layer is enforced AND
    // the request presented a cap_id. cap_id == 0 (default / legacy
    // clients) bypasses the filter, preserving backward compatibility.
    if (facade.usesCapFilter(cap_id)) {
        col.facade_for_filter = facade;
        col.cap_id = cap_id;
    }
    const enum_sink = kabi.FactSink{ .ctx = &col, .push = DumpAllCollector.push };
    facade.enumerate(scope, &enum_sink, Deadline.fromNow(5000)) catch {};

    // Pass 2: build the response.
    const prefix = std.fmt.bufPrint(
        out,
        "{{\"ok\":true,\"scope\":\"{s}\",\"items\":[",
        .{scope},
    ) catch return fmtErr(out, "fmt");
    var pos = prefix.len;

    // Reserve a tail to guarantee we can ALWAYS write a valid closing
    // suffix even when an inspect mid-stream fills the buffer. The
    // worst-case tail is `],"count":NNNNNN,"truncated":true}\n` ≈ 50 bytes;
    // 64 keeps a comfortable margin.
    const TAIL_RESERVE: usize = 64;

    var emitted: usize = 0;
    var truncated = col.overflowed; // enumerate already overflowed the URN cap

    var attrs_buf: [4096]u8 = undefined;

    for (col.urns[0..col.count]) |urn| {
        if (pos + TAIL_RESERVE >= out.len) {
            truncated = true;
            break;
        }
        // Per-URN inspect. A failure on one URN doesn't abort the
        // whole dump — we skip it and continue. This mirrors `list`'s
        // tolerance: enumerate-and-emit is best-effort across the
        // scope; a transient failure on one device must not make the
        // whole bulk read return empty.
        var attrs_writer = AttrJsonWriter{ .out = &attrs_buf };
        const attr_sink = kabi.AttrSink{
            .ctx = &attrs_writer,
            .push = AttrJsonWriter.push,
        };
        const res = facade.inspect(&urn, &attr_sink, Deadline.fromNow(1000)) catch continue;

        const sep = if (emitted == 0) "" else ",";
        const w = std.fmt.bufPrint(
            out[pos..],
            "{s}{{\"urn\":\"{s}\",\"family\":\"{s}\",\"kind\":\"{s}\",\"fidelity\":\"{s}\",\"attrs\":{{{s}}}}}",
            .{
                sep,
                res.urn.slice(),
                @tagName(res.family),
                @tagName(res.kind),
                @tagName(res.fidelity),
                attrs_writer.slice(),
            },
        ) catch {
            // Buffer filled mid-item; back off, mark truncated, write tail.
            truncated = true;
            break;
        };
        pos += w.len;
        emitted += 1;
    }

    const tail = std.fmt.bufPrint(
        out[pos..],
        "],\"count\":{d},\"truncated\":{}}}\n",
        .{ emitted, truncated },
    ) catch return fmtErr(out, "fmt");
    return out[0 .. pos + tail.len];
}

/// `inspect_full` op response (Part 13 §5.5.1). Walks the URN's
/// substrate subtree (sysfs for the Linux backends) and emits the
/// tree as nested JSON.
///
/// Response shape:
///   {"ok":true,
///    "urn":"hw:/usb/...",
///    "tree":{...},
///    "captured_at_ms":<broker-monotonic-ms>,
///    "truncated":<bool>}
///
/// `tree` is a recursive JSON object: regular files are
/// `"<name>":"<value>"`; symlinks are `"<name>":{"_symlink":"<target>"}`;
/// binary files are `"<name>":{"_binary":true}`; subdirectories are
/// nested objects keyed by name.
///
/// `truncated` is `true` when the walker hit its bounded entry / depth
/// cap; consumers either narrow the scope (use `shallow`) or accept
/// the partial view. The structure is always well-formed JSON even
/// when truncated — the walker emits balanced enter/leave pairs.
pub fn fmtInspectFull(
    facade: *facademod.Facade,
    urn: *const model.Urn,
    depth: model.InspectDepth,
    cap_id: u64,
    out: []u8,
) []const u8 {
    // R-T1-11B — capability-filtered enumeration for the single-URN
    // inspect. Unlike the scope-shaped ops there's no collector to wrap:
    // `inspect_full` targets ONE root URN, so the S3 check is on that
    // URN. When the cap filter applies and the root is outside the cap's
    // scope, return NotFound — the holder of an attenuated cap can't even
    // distinguish an out-of-scope URN from a nonexistent one (existence
    // itself is not observable beyond the grant, U11). The substrate
    // subtree below the root is sysfs structure, not broker URNs, so no
    // per-entry filtering applies once the root passes.
    if (facade.usesCapFilter(cap_id) and !facade.capPermitsNaming(cap_id, urn)) {
        return fmtErr(out, "NotFound");
    }
    // Build the `"tree":{...}` body into a side buffer; assemble the
    // final response with the basic Resource fields once the walk
    // finishes. Side buffer is sized for the walker's MAX_ENTRIES *
    // (key+value+overhead) worst case; 32 KiB is generous headroom.
    var tree_buf: [32768]u8 = undefined;
    var writer = TreeJsonWriter{ .out = &tree_buf };
    const sink = kabi.TreeSink{
        .ctx = &writer,
        .push_attr = TreeJsonWriter.pushAttr,
        .push_symlink = TreeJsonWriter.pushSymlink,
        .enter = TreeJsonWriter.enter,
        .leave = TreeJsonWriter.leave,
    };

    const res = facade.inspectFull(urn, depth, &sink, Deadline.fromNow(5_000)) catch |e|
        return fmtErr(out, errToWireCode(e));

    const captured = kabi.nowMs();
    const written = std.fmt.bufPrint(
        out,
        "{{\"ok\":true,\"urn\":\"{s}\",\"tree\":{{{s}}},\"captured_at_ms\":{d},\"truncated\":{}}}\n",
        .{
            res.urn.slice(),
            writer.slice(),
            captured,
            writer.truncated,
        },
    ) catch fmtErr(out, "fmt");
    return written;
}

/// Tree-shaped JSON serialiser for the `inspect_full` op. Wraps the
/// `kabi.TreeSink` calls into nested JSON-object syntax.
///
/// State machine:
///   • Each "level" tracks whether it has emitted at least one entry
///     (so a leading comma is correctly skipped on the first one).
///   • `enter("foo")` writes `,"foo":{` and pushes a fresh level.
///   • `leave()` writes `}` and pops back to the parent level.
///   • `push_attr` / `push_symlink` write the leaf at the current level.
///
/// The writer never emits OUTER braces — `fmtInspectFull` wraps the
/// produced body in `"tree":{...}`. That keeps this struct's job
/// scoped to "stream entries", separable from the response framing.
///
/// Overflow handling: when the side buffer fills mid-write, the
/// writer sets `truncated = true` and silently drops further pushes
/// (including enter/leave balance — the structure may be malformed
/// past that point, but `truncated` is the consumer's signal that
/// the response cannot be parsed as complete). At today's MAX_ENTRIES
/// (512) and typical key+value lengths, the 32 KiB side buffer
/// holds the full tree for any real-world device.
const TreeJsonWriter = struct {
    out: []u8,
    pos: usize = 0,
    /// Per-level "first entry?" tracking. Index 0 is the root; each
    /// `enter` pushes; each `leave` pops. Max depth bounded by
    /// `sysfs_walk.MAX_DEPTH` (16); we size 32 for headroom.
    /// `true` = next entry needs a leading comma; `false` = next is
    /// the first at this level.
    has_entry: [32]bool = [_]bool{false} ** 32,
    level: usize = 0,
    truncated: bool = false,

    fn slice(self: *const TreeJsonWriter) []const u8 {
        return self.out[0..self.pos];
    }

    /// Write raw bytes; on overflow set truncated + bail.
    fn write(self: *TreeJsonWriter, bytes: []const u8) void {
        if (self.pos + bytes.len > self.out.len) {
            self.truncated = true;
            return;
        }
        @memcpy(self.out[self.pos..][0..bytes.len], bytes);
        self.pos += bytes.len;
    }

    fn writeFmt(self: *TreeJsonWriter, comptime fmt: []const u8, args: anytype) void {
        const w = std.fmt.bufPrint(self.out[self.pos..], fmt, args) catch {
            self.truncated = true;
            return;
        };
        self.pos += w.len;
    }

    /// Emit the comma if this level has already had at least one entry.
    fn maybeSep(self: *TreeJsonWriter) void {
        if (self.has_entry[self.level]) self.write(",");
        self.has_entry[self.level] = true;
    }

    fn pushAttr(ctx: *anyopaque, key: []const u8, value: []const u8, is_binary: bool) void {
        const self: *TreeJsonWriter = @ptrCast(@alignCast(ctx));
        if (self.truncated) return;
        self.maybeSep();
        if (is_binary) {
            self.writeFmt("\"{s}\":{{\"_binary\":true}}", .{key});
        } else {
            // JSON-escape `value` defensively: sysfs attrs are
            // (overwhelmingly) printable ASCII after the binary
            // filter, but `"` and `\` can appear (e.g., a USB
            // device's `manufacturer` string with a quote).
            self.writeFmt("\"{s}\":\"", .{key});
            self.writeEscaped(value);
            self.write("\"");
        }
    }

    fn pushSymlink(ctx: *anyopaque, key: []const u8, target: []const u8) void {
        const self: *TreeJsonWriter = @ptrCast(@alignCast(ctx));
        if (self.truncated) return;
        self.maybeSep();
        self.writeFmt("\"{s}\":{{\"_symlink\":\"", .{key});
        self.writeEscaped(target);
        self.write("\"}");
    }

    fn enter(ctx: *anyopaque, key: []const u8) void {
        const self: *TreeJsonWriter = @ptrCast(@alignCast(ctx));
        if (self.truncated) return;
        if (self.level + 1 >= self.has_entry.len) {
            self.truncated = true;
            return;
        }
        self.maybeSep();
        self.writeFmt("\"{s}\":{{", .{key});
        self.level += 1;
        self.has_entry[self.level] = false;
    }

    fn leave(ctx: *anyopaque) void {
        const self: *TreeJsonWriter = @ptrCast(@alignCast(ctx));
        if (self.truncated) return;
        if (self.level == 0) return; // unbalanced; bail
        self.write("}");
        self.level -= 1;
    }

    /// JSON-escape a string into `out` at `pos`. Handles the small
    /// set of mandatory escapes (`"`, `\`, control chars). Non-ASCII
    /// printable passes through as-is (the substrate is byte-oriented
    /// and the binary-detect filter already routed away true binary).
    fn writeEscaped(self: *TreeJsonWriter, s: []const u8) void {
        for (s) |b| {
            if (self.truncated) return;
            switch (b) {
                '"' => self.write("\\\""),
                '\\' => self.write("\\\\"),
                '\n' => self.write("\\n"),
                '\r' => self.write("\\r"),
                '\t' => self.write("\\t"),
                else => {
                    if (b < 0x20) {
                        self.writeFmt("\\u{x:0>4}", .{b});
                    } else {
                        if (self.pos + 1 > self.out.len) {
                            self.truncated = true;
                            return;
                        }
                        self.out[self.pos] = b;
                        self.pos += 1;
                    }
                },
            }
        }
    }
};

/// `dump_chain` op response (Part 13 §5.5.2). Routes the URN to its
/// owner worker and asks the backend's chain walker to push one
/// `ChainEntry` per parent-chain rung; the writer streams them into
/// a JSON array body that `fmtDumpChain` wraps in the response.
///
/// Response shape:
///   {"ok":true,"urn":"...","chain":[
///     {"urn":"...","level":"interface","summary":"..."},
///     ...
///   ],"fidelity":"live","captured_at_ms":N,"truncated":false}
///
/// Truncation: a chain large enough to overflow the 8 KiB body is a
/// pathological substrate (real device chains are <10 rungs); the
/// writer sets `truncated=true` and stops appending. The structure
/// stays well-formed JSON because we emit balanced array brackets
/// in `fmtDumpChain` itself — the writer only emits ELEMENTS.
pub fn fmtDumpChain(
    facade: *facademod.Facade,
    urn: *const model.Urn,
    cap_id: u64,
    out: []u8,
) []const u8 {
    // R-T1-11D — capability-filtered enumeration for the single-URN
    // chain walk. The S3 check is on the named leaf URN; when the cap
    // filter applies and that URN is outside the cap's scope, return
    // NotFound (indistinguishable from a nonexistent URN). The parent
    // chain above the leaf is substrate topology context, not
    // separately-claimable URNs, so no per-entry filtering applies once
    // the leaf passes. Same shape as `fmtInspectFull`.
    if (facade.usesCapFilter(cap_id) and !facade.capPermitsNaming(cap_id, urn)) {
        return fmtErr(out, "NotFound");
    }
    var chain_buf: [8192]u8 = undefined;
    var writer = ChainJsonWriter{ .out = &chain_buf };
    const sink = kabi.ChainSink{
        .ctx = &writer,
        .push = ChainJsonWriter.push,
    };

    facade.dumpChain(urn, &sink, Deadline.fromNow(5_000)) catch |e|
        return fmtErr(out, errToWireCode(e));

    const captured = kabi.nowMs();
    const written = std.fmt.bufPrint(
        out,
        "{{\"ok\":true,\"urn\":\"{s}\",\"chain\":[{s}],\"fidelity\":\"live\",\"captured_at_ms\":{d},\"truncated\":{}}}\n",
        .{
            urn.slice(),
            writer.slice(),
            captured,
            writer.truncated,
        },
    ) catch fmtErr(out, "fmt");
    return written;
}

/// JSON serialiser for the `dump_chain` op. One `push` call becomes
/// one `{"urn":"...","level":"...","summary":"..."}` element,
/// comma-separated; the wrapping array brackets are added by
/// `fmtDumpChain`. JSON-escapes the summary defensively (URN /
/// level are wire-pinned charsets, so they pass through; summary
/// is human text that can include any byte).
const ChainJsonWriter = struct {
    out: []u8,
    pos: usize = 0,
    has_entry: bool = false,
    truncated: bool = false,

    fn slice(self: *const ChainJsonWriter) []const u8 {
        return self.out[0..self.pos];
    }

    fn write(self: *ChainJsonWriter, bytes: []const u8) void {
        if (self.pos + bytes.len > self.out.len) {
            self.truncated = true;
            return;
        }
        @memcpy(self.out[self.pos..][0..bytes.len], bytes);
        self.pos += bytes.len;
    }

    fn writeFmt(self: *ChainJsonWriter, comptime fmt: []const u8, args: anytype) void {
        const w = std.fmt.bufPrint(self.out[self.pos..], fmt, args) catch {
            self.truncated = true;
            return;
        };
        self.pos += w.len;
    }

    fn writeEscaped(self: *ChainJsonWriter, s: []const u8) void {
        for (s) |b| {
            if (self.truncated) return;
            switch (b) {
                '"' => self.write("\\\""),
                '\\' => self.write("\\\\"),
                '\n' => self.write("\\n"),
                '\r' => self.write("\\r"),
                '\t' => self.write("\\t"),
                else => {
                    if (b < 0x20) {
                        self.writeFmt("\\u{x:0>4}", .{b});
                    } else {
                        if (self.pos + 1 > self.out.len) {
                            self.truncated = true;
                            return;
                        }
                        self.out[self.pos] = b;
                        self.pos += 1;
                    }
                },
            }
        }
    }

    fn push(ctx: *anyopaque, e: kabi.ChainEntry) void {
        const self: *ChainJsonWriter = @ptrCast(@alignCast(ctx));
        if (self.truncated) return;
        if (self.has_entry) self.write(",");
        self.has_entry = true;
        self.writeFmt("{{\"urn\":\"{s}\",\"level\":\"{s}\",\"summary\":\"", .{ e.urn, e.level });
        self.writeEscaped(e.summary);
        self.write("\"}");
    }
};

/// `driver_info` op response (Part 13 §5.2.2). Reports the broker-
/// visible interface of a kernel driver: load state, bound-device
/// count, sysfs attrs exposed on a bound device, plus registry-
/// derived fields (curated YAML from §5.2.3 — ships in sub-phase
/// 3B; v1 emits them as null/empty).
///
/// Live data sources:
///   * `module_loaded` ← /sys/module/<name>/ directory exists.
///   * `bound_count`   ← entries in /sys/bus/<bus>/drivers/<name>/
///                       across the buses the broker knows about.
///   * `sample_bound_urn` ← the first bound device's symlink
///                       basename (best-effort; null if none bound).
///   * `sysfs_attrs`   ← TODO — walk the first bound device's
///                       sysfs attr dir in a follow-up. Empty in v1
///                       (the device-attr walker exists in
///                       sysfs_walk.zig but its output shape would
///                       overwhelm the response; a CURATED attr
///                       list lives in the 3B registry instead).
///
/// Registry-derived fields (all null/empty in v1; 3B fills them):
///   * `module`             — the loaded-module name (often == driver name)
///   * `ioctls`             — list of ioctl numbers + types
///   * `char_devices`       — /dev nodes the driver creates
///   * `uevent_actions`     — kernel uevent actions
///   * `registry_version`   — date the YAML entry was verified
///
/// `fidelity` is "inferred" because the registry half is missing in
/// v1. When 3B lands and the registry is present, the value becomes
/// "live" for in-registry drivers, "unknown" for not-in-registry.
///
/// Honest emptiness for drivers absent from the kernel: no NotFound
/// — the response still carries the shape with `module_loaded:false,
/// bound_count:0`, so consumers learn "driver not present here"
/// without needing a separate exception path.
pub fn fmtDriverInfo(name: []const u8, out: []u8) []const u8 {
    var path_buf: [256]u8 = undefined;

    // /sys/module/<name>/ — directory exists iff the module is loaded
    // (built-in modules also have a /sys/module entry, so this is
    // really "module-or-builtin loaded").
    const mod_path = std.fmt.bufPrintZ(
        &path_buf,
        "/sys/module/{s}",
        .{name},
    ) catch return fmtErr(out, "BadRequest");
    const module_loaded = dirExists(mod_path);

    // Count bound devices across known driver dirs.
    var bound_total: u32 = 0;
    var sample_buf: [128]u8 = undefined;
    var sample_len: usize = 0;
    for ([_][]const u8{
        "/sys/bus/usb/drivers",
        "/sys/bus/pci/drivers",
    }) |bus_drivers_dir| {
        var drv_path_buf: [256]u8 = undefined;
        const drv_path = std.fmt.bufPrintZ(
            &drv_path_buf,
            "{s}/{s}",
            .{ bus_drivers_dir, name },
        ) catch continue;
        bound_total += countDriverHolders(drv_path, &sample_buf, &sample_len);
    }

    // Look up the curated registry. Present → splice the registry
    // fields (Part 13 §5.2.3 sub-phase 3B); absent → null fields,
    // fidelity drops to "unknown" so the consumer knows the
    // registry has no entry for this driver.
    const reg = driver_registry.lookup(name);

    var w = ResponseWriter{ .out = out };
    w.writeFmt("{{\"ok\":true,\"name\":\"{s}\"", .{name});
    if (reg) |e| {
        w.writeFmt(",\"module\":\"{s}\"", .{e.module});
    } else {
        w.write(",\"module\":null");
    }
    w.writeFmt(",\"module_loaded\":{}", .{module_loaded});
    w.writeFmt(",\"bound_count\":{d}", .{bound_total});
    if (sample_len > 0) {
        w.writeFmt(",\"sample_bound\":\"{s}\"", .{sample_buf[0..sample_len]});
    } else {
        w.write(",\"sample_bound\":null");
    }
    // sysfs_attrs stays empty in 3B v1; future curated extension
    // (or a per-driver attr walker) lights it up.
    w.write(",\"sysfs_attrs\":[]");
    if (reg) |e| {
        writeIoctlsJson(&w, e.ioctls);
        writeCharDevicesJson(&w, e.char_devices);
        writeStringArrayJson(&w, "uevent_actions", e.uevent_actions);
        w.writeFmt(",\"registry_version\":\"{s}\"", .{e.last_verified});
        // Live half + curated registry both present → fidelity
        // is "live" for the in-registry rungs; the wrapper is
        // honest because both sides agreed.
        w.write(",\"fidelity\":\"live\"");
    } else {
        w.write(",\"ioctls\":null,\"char_devices\":null,\"uevent_actions\":null,\"registry_version\":null");
        // Out-of-registry driver — honestly "unknown" rather
        // than "inferred" (we have NO registry view at all).
        w.write(",\"fidelity\":\"unknown\"");
    }
    w.write("}\n");
    return w.slice();
}

/// Tiny scratch writer the driver_info formatter uses. Same shape
/// as the in-place writers in this file but local because nothing
/// else needs it; consolidating is yet-future refactor work.
const ResponseWriter = struct {
    out: []u8,
    pos: usize = 0,
    overflow: bool = false,

    fn slice(self: *const ResponseWriter) []const u8 {
        return self.out[0..self.pos];
    }
    fn write(self: *ResponseWriter, bytes: []const u8) void {
        if (self.overflow) return;
        if (self.pos + bytes.len > self.out.len) {
            self.overflow = true;
            return;
        }
        @memcpy(self.out[self.pos..][0..bytes.len], bytes);
        self.pos += bytes.len;
    }
    fn writeFmt(self: *ResponseWriter, comptime fmt: []const u8, args: anytype) void {
        if (self.overflow) return;
        const w = std.fmt.bufPrint(self.out[self.pos..], fmt, args) catch {
            self.overflow = true;
            return;
        };
        self.pos += w.len;
    }
};

fn writeIoctlsJson(w: *ResponseWriter, ioctls: []driver_registry.Ioctl) void {
    w.write(",\"ioctls\":[");
    for (ioctls, 0..) |io, i| {
        const sep = if (i == 0) "" else ",";
        // Variable-size entries surface `base_number` +
        // `variable_size:true`; fixed entries surface `number`.
        // Consumers see the same wire shape that the JSON
        // registry files carry — round-trip-stable.
        if (io.variable_size) {
            w.writeFmt(
                "{s}{{\"name\":\"{s}\",\"base_number\":\"{s}\"" ++
                    ",\"variable_size\":true" ++
                    ",\"arg\":\"{s}\",\"direction\":\"{s}\"}}",
                .{ sep, io.name, io.number_hex, io.arg, io.direction },
            );
        } else {
            w.writeFmt(
                "{s}{{\"name\":\"{s}\",\"number\":\"{s}\"" ++
                    ",\"arg\":\"{s}\",\"direction\":\"{s}\"}}",
                .{ sep, io.name, io.number_hex, io.arg, io.direction },
            );
        }
    }
    w.write("]");
}

fn writeCharDevicesJson(w: *ResponseWriter, cds: []driver_registry.CharDevice) void {
    w.write(",\"char_devices\":[");
    for (cds, 0..) |cd, i| {
        const sep = if (i == 0) "" else ",";
        w.writeFmt(
            "{s}{{\"pattern\":\"{s}\",\"permissions\":\"{s}\"}}",
            .{ sep, cd.pattern, cd.permissions },
        );
    }
    w.write("]");
}

fn writeStringArrayJson(w: *ResponseWriter, key: []const u8, items: [][]const u8) void {
    w.writeFmt(",\"{s}\":[", .{key});
    for (items, 0..) |s, i| {
        const sep = if (i == 0) "" else ",";
        w.writeFmt("{s}\"{s}\"", .{ sep, s });
    }
    w.write("]");
}

/// Does the directory at `path` exist?
fn dirExists(path: [:0]const u8) bool {
    const rc = linux.open(path, .{ .ACCMODE = .RDONLY, .DIRECTORY = true }, 0);
    if (linux.errno(rc) != .SUCCESS) return false;
    _ = linux.close(@intCast(rc));
    return true;
}

/// Count entries in a `/sys/bus/<bus>/drivers/<name>/` directory
/// that look like bound-device symlinks (i.e. not the well-known
/// driver-control files). Captures the first bound entry's name
/// into `sample_buf` for the response's `sample_bound` field (used
/// by consumers as "the first device this driver owns" for an
/// at-a-glance inspect target).
fn countDriverHolders(
    dir_path: [:0]const u8,
    sample_buf: []u8,
    sample_len: *usize,
) u32 {
    const fd_rc = linux.open(
        dir_path,
        .{ .ACCMODE = .RDONLY, .DIRECTORY = true },
        0,
    );
    if (linux.errno(fd_rc) != .SUCCESS) return 0;
    const fd: i32 = @intCast(fd_rc);
    defer _ = linux.close(fd);

    var count: u32 = 0;
    var buf: [4096]u8 align(@alignOf(linux.dirent64)) = undefined;
    while (true) {
        const n = linux.getdents64(fd, &buf, buf.len);
        if (linux.errno(n) != .SUCCESS) return count;
        if (n == 0) return count;
        var pos: usize = 0;
        while (pos < n) {
            const dent: *linux.dirent64 = @ptrCast(@alignCast(&buf[pos]));
            pos += dent.reclen;
            const name_ptr: [*:0]const u8 = @ptrCast(&dent.name);
            const name = std.mem.span(name_ptr);
            // Skip `.`, `..`, and the driver-control pseudo-files
            // (`bind`, `unbind`, `uevent`, `module`, `new_id`,
            // `remove_id`, `rebind`). The remaining entries are
            // symlinks to bound device sysfs dirs.
            if (std.mem.eql(u8, name, ".") or std.mem.eql(u8, name, "..")) continue;
            if (std.mem.eql(u8, name, "bind") or
                std.mem.eql(u8, name, "unbind") or
                std.mem.eql(u8, name, "uevent") or
                std.mem.eql(u8, name, "module") or
                std.mem.eql(u8, name, "new_id") or
                std.mem.eql(u8, name, "remove_id") or
                std.mem.eql(u8, name, "rebind")) continue;
            count += 1;
            // Capture first bound entry's name for the sample field.
            if (sample_len.* == 0 and name.len <= sample_buf.len) {
                @memcpy(sample_buf[0..name.len], name);
                sample_len.* = name.len;
            }
        }
    }
}

/// `audit_tail` op response (Part 13 §5.6.4). Returns up to `n`
/// most-recent records from the audit ring — newest first. Each
/// record renders as a compact JSON object carrying the fields
/// the consumer needs to reconstruct a causal trace:
/// `seq`, `ts_ms`, `duration_us`, `op`, `urn?`, `outcome`,
/// `err?`, `correlation_id?`, `peer_uid`, `peer_pid`, `cap_id`.
///
/// Gated by the `audit_read` right (Part 13 §8). The caller's
/// cap_id is verified against the broker's CapTable + the
/// SO_PEERCRED-bound peer; failure surfaces as NotPermitted.
pub fn fmtAuditTail(
    facade: *facademod.Facade,
    peer: cap.PeerCred,
    cap_id: u64,
    n: u32,
    out: []u8,
) []const u8 {
    if (facade.verifier) |ct| {
        if (!ct.permitsAuditReadFromPeer(cap_id, peer)) {
            return fmtErr(out, "NotPermitted");
        }
    }
    var snap_buf: [256]audit.AuditRecord = undefined;
    const cap_n: usize = @min(@as(usize, n), snap_buf.len);
    const got = audit.snapshot(cap_n, snap_buf[0..]);
    const c = audit.counters();

    var w = ResponseWriter{ .out = out };
    w.writeFmt(
        "{{\"ok\":true,\"records\":[",
        .{},
    );
    var i: usize = 0;
    var earliest_ts: u64 = 0;
    while (i < got) : (i += 1) {
        const r = &snap_buf[i];
        if (i == 0 or r.ts_ms < earliest_ts) earliest_ts = r.ts_ms;
        const sep = if (i == 0) "" else ",";
        w.writeFmt(
            "{s}{{\"seq\":{d}" ++
                ",\"ts_ms\":{d}" ++
                ",\"duration_us\":{d}" ++
                ",\"op\":\"{s}\"" ++
                ",\"outcome\":\"{s}\"" ++
                ",\"peer_uid\":{d}" ++
                ",\"peer_pid\":{d}" ++
                ",\"cap_id\":{d}",
            .{
                sep,
                r.seq,
                r.ts_ms,
                r.duration_us,
                r.op(),
                r.outcome.name(),
                r.peer_uid,
                r.peer_pid,
                r.cap_id,
            },
        );
        if (r.urn()) |u| w.writeFmt(",\"urn\":\"{s}\"", .{u});
        if (r.errCode()) |code| w.writeFmt(",\"err\":\"{s}\"", .{code});
        if (r.correlationId()) |cid| w.writeFmt(",\"correlation_id\":\"{s}\"", .{cid});
        w.write("}");
    }
    w.writeFmt(
        "],\"ring_capacity\":{d},\"earliest_ts_ms\":{d}}}\n",
        .{ c.ring_capacity, earliest_ts },
    );
    return w.slice();
}

/// `state_snapshot` op response (Part 13 §5.6.2). Aggregates
/// broker-wide counters into one diagnostic payload. Cheap —
/// every value is in-memory.
///
/// v1 omits a few spec-listed fields:
///   * `ops_per_second_1m` — needs a sliding-window tracker;
///     deferred to a follow-up.
///   * `memory.rss_bytes` / `allocator_high_water_bytes` — OS-
///     specific reads (`/proc/self/statm`); not wired today.
///   * `cap_table_size` — would require a new method on
///     `cap.CapTable`; small but cross-cutting, deferred.
///
/// The fields ARE present:
///   * `ts_ms`, `uptime_ms`, `broker_version`
///   * `ops_total`, `active_connections`, `active_leases`,
///     `active_subscriptions`, `audit_ring_used`,
///     `audit_ring_capacity`
///   * `workers` — per-worker `backend_name` / `mode` / `url_count`
///   * `fidelity:"live"` (set by the auto-splice in handle())
pub fn fmtStateSnapshot(
    facade: *facademod.Facade,
    peer: cap.PeerCred,
    cap_id: u64,
    out: []u8,
) []const u8 {
    if (facade.verifier) |ct| {
        if (!ct.permitsAuditReadFromPeer(cap_id, peer)) {
            return fmtErr(out, "NotPermitted");
        }
    }
    const c = audit.counters();
    const sub_count = subscription.count();

    // Active leases: sum across workers via the existing list_leases
    // pathway. A counting helper is cheaper than building the
    // typed list — same shape as `fmtCapabilities`' use of
    // `CountSink`. For now we just call drainLeases-counting via
    // a quick walk; if this becomes a hot path, add a per-worker
    // lease-count helper to the facade.
    var lease_count: u32 = 0;
    {
        var counter = LeaseCountSink{};
        const sink = core_mod.LeaseSink{ .ctx = &counter, .push = LeaseCountSink.push };
        facade.listLeases("hw:/**", &sink);
        lease_count = counter.n;
    }

    // Part 13 §5.6.2 — `ops_per_second_1m` from the ring's
    // own timestamps. When uptime < 60s, this reports ops-so-far
    // (the consumer can compare against `uptime_ms` to gauge
    // representativeness).
    const ops_in_1m: u32 = audit.opsInLastMs(60_000);
    const ops_per_sec_1m_x100: u64 = (@as(u64, ops_in_1m) * 100) / 60;

    // cap_table_size — number of live caps. The verifier may
    // be absent in some constellations (the tests use one),
    // in which case the field reports 0.
    const cap_size: usize = if (facade.verifier) |ct| ct.size() else 0;

    // /proc/self/statm — "size resident shared text lib data dt"
    // in PAGES. rss_bytes = resident × page_size. Linux only;
    // any read failure falls back to 0 (honest emptiness — the
    // field is still present in the response so the SDK shape
    // stays stable across platforms).
    const rss_bytes: u64 = readRssBytes() catch 0;

    var w = ResponseWriter{ .out = out };
    w.writeFmt(
        "{{\"ok\":true" ++
            ",\"ts_ms\":{d}" ++
            ",\"uptime_ms\":{d}" ++
            ",\"broker_version\":\"0.1.0\"" ++
            ",\"ops_total\":{d}" ++
            ",\"ops_per_second_1m\":{d}.{d:0>2}" ++
            ",\"active_connections\":{d}" ++
            ",\"active_leases\":{d}" ++
            ",\"active_subscriptions\":{d}" ++
            ",\"cap_table_size\":{d}" ++
            ",\"audit_ring_used\":{d}" ++
            ",\"audit_ring_capacity\":{d}" ++
            ",\"audit_dropped_total\":{d}" ++
            ",\"memory\":{{\"rss_bytes\":{d}}}" ++
            ",\"workers\":{{",
        .{
            kabi.nowMs(),
            c.uptime_ms,
            c.ops_total,
            ops_per_sec_1m_x100 / 100,
            ops_per_sec_1m_x100 % 100,
            c.active_connections,
            lease_count,
            sub_count,
            cap_size,
            c.ring_used,
            c.ring_capacity,
            c.dropped_total,
            rss_bytes,
        },
    );
    for (facade.workers, 0..) |worker, i| {
        var counter = CountSink{};
        const cs = kabi.FactSink{ .ctx = &counter, .push = CountSink.push };
        worker.core.backend.enumerate("hw:/**", &cs, Deadline.fromNow(2_000)) catch {};
        const caps = worker.core.backend.capabilities();
        const sep = if (i == 0) "" else ",";
        w.writeFmt(
            "{s}\"{s}\":{{\"backend\":\"{s}\",\"mode\":\"{s}\",\"url_count\":{d}}}",
            .{
                sep,
                worker.scope_prefix,
                caps.name,
                @tagName(caps.mode),
                counter.n,
            },
        );
    }
    w.write("}}\n");
    return w.slice();
}

/// Read this process's resident-set size in bytes from
/// `/proc/self/statm`. The file's second field is "resident" in
/// page units; multiplied by `sysconf(_SC_PAGESIZE)` (4096 on
/// every Linux we care about) gives bytes.
///
/// Linux-only. Any read failure surfaces as an error the caller
/// can fold into "report 0" — the broker's state_snapshot
/// field is best-effort, not load-bearing.
fn readRssBytes() !u64 {
    const fd_rc = linux.open(
        "/proc/self/statm",
        .{ .ACCMODE = .RDONLY },
        0,
    );
    if (linux.errno(fd_rc) != .SUCCESS) return error.OpenFailed;
    const fd: i32 = @intCast(fd_rc);
    defer _ = linux.close(fd);
    var buf: [256]u8 = undefined;
    const n = linux.read(fd, &buf, buf.len);
    if (linux.errno(n) != .SUCCESS) return error.ReadFailed;
    const slice = buf[0..n];

    // Parse "<size> <resident> ...". Skip the first whitespace-
    // delimited token (size); the next is `resident` in pages.
    var it = std.mem.tokenizeAny(u8, slice, " \t\n");
    _ = it.next() orelse return error.MalformedStatm;
    const resident_str = it.next() orelse return error.MalformedStatm;
    const resident_pages = std.fmt.parseInt(u64, resident_str, 10) catch
        return error.MalformedStatm;
    // sysconf(_SC_PAGESIZE) — getauxval(AT_PAGESZ) would also
    // work but std.os doesn't expose it cleanly in Zig 0.16.
    // 4096 is correct on every Linux amd64/arm64 host today.
    const page_size: u64 = 4096;
    return resident_pages * page_size;
}

/// Counting-only sink: increments per `push` without recording the
/// LeaseRecord. Used by `fmtStateSnapshot` to count active leases
/// across all workers without buffering the rows.
const LeaseCountSink = struct {
    n: u32 = 0,
    fn push(ctx: *anyopaque, _: core_mod.LeaseRecord) void {
        const self: *LeaseCountSink = @ptrCast(@alignCast(ctx));
        self.n += 1;
    }
};

/// Counting-only sink: increments per `push` without recording the Resource.
/// Used by `fmtCapabilities` to report per-worker resource counts cheaply
/// without buffering the whole enumeration.
const CountSink = struct {
    n: usize = 0,
    fn push(ctx: *anyopaque, _: model.Resource) void {
        const self: *CountSink = @ptrCast(@alignCast(ctx));
        self.n += 1;
    }
};

/// `capabilities` op response (FEEDBACK TOOLS-01 / Part 6.2.1). Returns the
/// broker's worker constellation as a JSON array — one entry per worker
/// carrying its scope prefix, the backend's name/version, per-op support
/// booleans, operating mode + reason, and live resource count. Consumers
/// like `mgf-hrb doctor` use this to render which substrates the broker
/// has wired and exactly what each one supports without probing every op.
pub fn fmtCapabilities(facade: *facademod.Facade, out: []u8) []const u8 {
    // Part 13 §7.3 — the predicate grammar's wire version. Consumers
    // that build a `subscribe` predicate query this BEFORE sending,
    // so they can downgrade unknown features rather than discover
    // BadRequest at runtime. v1 is "1.0.0" — shipping the subscribe
    // op + the full grammar (kind_in, urn_glob, attr_eq, attr_in,
    // all_of, any_of, not) in one piece. Future grammar growth bumps
    // this; subtractive changes are disallowed by the OCP discipline.
    const prefix =
        "{\"ok\":true," ++
        "\"predicate_grammar_version\":\"1.0.0\"," ++
        "\"backends\":[";
    @memcpy(out[0..prefix.len], prefix);
    var pos: usize = prefix.len;

    for (facade.workers, 0..) |w, i| {
        // Per-worker resource count via a counting sink. The whole-scope
        // enumerate ("hw:/**") narrows to this worker because the facade
        // routes by scope_prefix; calling the backend directly here is the
        // same result without going back through the facade layer.
        var counter = CountSink{};
        const cs = kabi.FactSink{ .ctx = &counter, .push = CountSink.push };
        w.core.backend.enumerate("hw:/**", &cs, Deadline.fromNow(5_000)) catch {};

        // Per-backend capabilities report (kabi §6.2.1).
        const c = w.core.backend.capabilities();

        const sep = if (i == 0) "" else ",";
        const written = std.fmt.bufPrint(
            out[pos..],
            "{s}{{\"scope_prefix\":\"{s}\"" ++
                ",\"backend_name\":\"{s}\"" ++
                ",\"backend_version\":\"{s}\"" ++
                ",\"resource_count\":{d}" ++
                ",\"mode\":\"{s}\"" ++
                ",\"mode_reason\":\"{s}\"" ++
                ",\"ops\":{{" ++
                "\"enumerate\":{}" ++
                ",\"query_topology\":{}" ++
                ",\"watch\":{}" ++
                ",\"acquire\":{}" ++
                ",\"release\":{}" ++
                ",\"reset\":{}" ++
                ",\"map_region\":{}" ++
                ",\"raw_channel\":{}" ++
                ",\"enforce_cap\":{}" ++
                "}}}}",
            .{
                sep,
                w.scope_prefix,
                c.name,
                c.version,
                counter.n,
                @tagName(c.mode),
                c.mode_reason,
                c.op_enumerate,
                c.op_query_topology,
                c.op_watch,
                c.op_acquire,
                c.op_release,
                c.op_reset,
                c.op_map_region,
                c.op_raw_channel,
                c.op_enforce_cap,
            },
        ) catch break;
        pos += written.len;
    }

    const suffix = "]}\n";
    @memcpy(out[pos..][0..suffix.len], suffix);
    return out[0 .. pos + suffix.len];
}
