Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -575,7 +575,12 @@ public extension DiagnosticEventCode {
.discoveryStarted, .discoverySucceeded, .discoveryFailed,
.admissionSucceeded, .admissionFailed,
.transportSessionLifecycle,
.transportCloseAttribution, .transportPathEvent:
.transportCloseAttribution, .transportPathEvent,
.transportDialPlanBuilt, .transportPrivateAddressJoin,
.transportLANDiscovery, .transportDialLegSucceeded,
.transportDialLegFailed, .lanPublicationState,
.transportDialSessionLinked, .transportDialCancelled,
.transportCloseReason:
return .network
case .appLifecycleChanged, .reachabilityChanged:
return .both
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,15 @@ public protocol CmxByteTransportContinuityIdentifying: CmxByteTransport {
func transportContinuityID() async -> UInt64?
}

/// Optional privacy-safe link from a byte dial to the admitted transport
/// session that backs it. The value is process-local and never leaves the
/// diagnostic ring.
public protocol CmxByteTransportDiagnosticSessionIdentifying: CmxByteTransport {
/// Returns the current admitted session ID, or `nil` before connection or
/// after the session has been released.
func transportDiagnosticSessionID() async -> Int?
}

/// A privacy-safe handle that waits for one exact native transport to close.
///
/// The handle captures the transport generation at creation time, so callers
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import Foundation

/// Builds the short identity printed in every exported network report.
///
/// The git SHA and dev tag are signed bundle metadata, not runtime input. The
/// helper keeps iOS and macOS reports comparable and applies the same bounded
/// sanitization at their shared boundary.
public enum DiagnosticBuildStamp {
/// Returns a bounded `name version (build) tag sha` stamp from bundle data.
public static func make(
infoDictionary: [String: Any]?,
fallbackName: String = "cmux"
) -> String {
let info = infoDictionary ?? [:]
let name = nonEmptyString(info["CFBundleName"]) ?? fallbackName
let version = nonEmptyString(info["CFBundleShortVersionString"]) ?? "?"
let build = nonEmptyString(info["CFBundleVersion"]) ?? "?"
let tag = nonEmptyString(info["CMUXDevTag"])
let sha = nonEmptyString(info["CMUXGitSHA"]).map {
String($0.prefix(12))
}

var result = "\(name) \(version) (\(build))"
if let tag {
result += " tag \(tag)"
}
if let sha {
result += " sha \(sha)"
}
return DiagnosticReport.sanitizeBuildStamp(result)
}

private static func nonEmptyString(_ value: Any?) -> String? {
guard let value = value as? String else { return nil }
let trimmed = value.trimmingCharacters(in: .whitespacesAndNewlines)
return trimmed.isEmpty ? nil : trimmed
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -258,20 +258,47 @@ public enum DiagnosticEventCode: UInt16, Sendable, Codable, CaseIterable {
/// account identifiers, file paths, URLs, workspace titles, or error text.
case appFeatureAction = 65

// MARK: Relay-free bootstrap diagnostics
// Raw values 66-70 are reserved for app-wide diagnostic expansion.

/// A privacy-safe count of public/private dial candidates before dialing.
// MARK: Iroh bootstrap diagnostics

/// One direct dial plan was assembled before any connect attempt. `a` is
/// the public path hint count and `b` is the private fallback path hint
/// count. A plan with both counts zero proves no dial packet was sent.
case transportDialPlanBuilt = 71
/// A configured private address was joined to an authenticated endpoint.
/// Configured private addresses were joined with the target Mac's
/// broker-registered UDP port for one dial. `a` is the join state
/// (``DiagnosticPrivateAddressJoinState``), `b` is the configured
/// address count, and `c` is the resulting dialable hint count.
case transportPrivateAddressJoin = 72
/// LAN discovery completed without retaining addresses in diagnostics.
/// Account-private LAN discovery resolved for one dial. `a` is the
/// outcome (``DiagnosticLANDiscoveryOutcome``) and `b` is the resolved
/// hint count.
case transportLANDiscovery = 73
/// One direct/private dial leg succeeded.
/// One direct dial leg connected. `a` is the leg
/// (``DiagnosticDirectDialLeg``).
case transportDialLegSucceeded = 74
/// One direct/private dial leg failed. `b` is ``DiagnosticFailureKind``.
/// One direct dial leg failed before a connection existed. `a` is the
/// leg (``DiagnosticDirectDialLeg``) and `b` is the classified
/// ``DiagnosticFailureKind``.
case transportDialLegFailed = 75
/// Mac LAN publication changed state without exposing addresses.
/// The Mac's account-private LAN advertisement changed publication
/// state. `a` is the state (``DiagnosticLANPublicationState``) and `b`
/// is the synchronization reason (0 applied, 1 listener setting
/// disabled, 2 runtime context unavailable).
case lanPublicationState = 76

/// The transport dial was associated with the admitted session it opened.
/// `surface` is the process-local peer alias, `a` is the dial attempt ID,
/// and `c` is the matching session ID.
case transportDialSessionLinked = 77
/// A pending dial was cancelled by a lifecycle owner. `surface` is the
/// peer alias, `a` is ``DiagnosticCancellationReason``, `ms` is elapsed
/// dial time, and `c` is the dial attempt ID.
case transportDialCancelled = 78
/// A close carried a bounded remote reason token. `surface` is the peer
/// alias, `a` is ``DiagnosticRemoteCloseReason``, and `c` is the session ID.
case transportCloseReason = 79
}

/// Scene phase carried by ``DiagnosticEventCode/appLifecycleChanged``.
Expand Down
Loading