diff --git a/apps/examples/crypto_example.zig b/apps/examples/crypto_example.zig index e0da8ec..ebf3bba 100644 --- a/apps/examples/crypto_example.zig +++ b/apps/examples/crypto_example.zig @@ -46,6 +46,7 @@ pub fn main() !void { plaintext, recipient_public, sender_private, + crypto.EncryptedPayload.SERVICE_FEED, allocator, ); defer encrypted.deinit(allocator); @@ -65,7 +66,7 @@ pub fn main() !void { std.debug.print(" Total encrypted size: {} bytes\n\n", .{encrypted.size()}); // Decrypt - const decrypted = try crypto.decryptPayload(&encrypted, recipient_private, allocator); + const decrypted = try crypto.decryptPayload(&encrypted, recipient_private, crypto.EncryptedPayload.SERVICE_FEED, allocator); defer allocator.free(decrypted); std.debug.print("4. Decrypted message:\n", .{}); diff --git a/apps/examples/lwf_example.zig b/apps/examples/lwf_example.zig index 4cae5fa..b807e4c 100644 --- a/apps/examples/lwf_example.zig +++ b/apps/examples/lwf_example.zig @@ -4,7 +4,6 @@ const std = @import("std"); const l0_transport = @import("l0_transport"); -const lwf = l0_transport.lwf; pub fn main() !void { var gpa = std.heap.GeneralPurposeAllocator(.{}){}; @@ -16,19 +15,19 @@ pub fn main() !void { std.debug.print("===================================\n\n", .{}); // Create LWF frame - var frame = try lwf.LWFFrame.init(allocator, 100); + var frame = try l0_transport.LWFFrame.init(allocator, 100); defer frame.deinit(allocator); std.debug.print("1. Created LWF frame:\n", .{}); - std.debug.print(" Header size: {} bytes\n", .{lwf.LWFHeader.SIZE}); + std.debug.print(" Header size: {} bytes\n", .{l0_transport.LWFHeader.SIZE}); std.debug.print(" Payload size: {} bytes\n", .{frame.payload.len}); - std.debug.print(" Trailer size: {} bytes\n", .{lwf.LWFTrailer.SIZE}); + std.debug.print(" Trailer size: {} bytes\n", .{l0_transport.LWFTrailer.SIZE}); std.debug.print(" Total size: {} bytes\n\n", .{frame.size()}); // Set frame headers frame.header.service_type = std.mem.nativeToBig(u16, 0x0A00); // FEED_WORLD_POST - frame.header.flags = lwf.LWFFlags.ENCRYPTED | lwf.LWFFlags.SIGNED; - frame.header.frame_class = @intFromEnum(lwf.FrameClass.standard); + frame.header.flags = l0_transport.LWFFlags.ENCRYPTED | l0_transport.LWFFlags.SIGNED; + frame.header.frame_class = @intFromEnum(l0_transport.FrameClass.standard); frame.header.timestamp = std.mem.nativeToBig(u64, @as(u64, @intCast(std.time.timestamp()))); frame.header.payload_len = std.mem.nativeToBig(u16, @as(u16, @intCast(frame.payload.len))); @@ -39,14 +38,14 @@ pub fn main() !void { std.debug.print("2. Populated frame:\n", .{}); std.debug.print(" Service type: 0x{X:0>4}\n", .{std.mem.bigToNative(u16, frame.header.service_type)}); std.debug.print(" Flags: 0x{X:0>2} ", .{frame.header.flags}); - if (frame.header.flags & lwf.LWFFlags.ENCRYPTED != 0) { + if (frame.header.flags & l0_transport.LWFFlags.ENCRYPTED != 0) { std.debug.print("(ENCRYPTED) ", .{}); } - if (frame.header.flags & lwf.LWFFlags.SIGNED != 0) { + if (frame.header.flags & l0_transport.LWFFlags.SIGNED != 0) { std.debug.print("(SIGNED) ", .{}); } std.debug.print("\n", .{}); - std.debug.print(" Frame class: {s}\n", .{@tagName(lwf.FrameClass.standard)}); + std.debug.print(" Frame class: {s}\n", .{@tagName(l0_transport.FrameClass.standard)}); std.debug.print(" Payload: \"{s}\"\n\n", .{message}); // Calculate and set checksum @@ -69,7 +68,7 @@ pub fn main() !void { std.debug.print("\n\n", .{}); // Decode frame back - var decoded = try lwf.LWFFrame.decode(allocator, encoded); + var decoded = try l0_transport.LWFFrame.decode(allocator, encoded); defer decoded.deinit(allocator); std.debug.print("5. Decoded frame:\n", .{}); diff --git a/build.zig b/build.zig index 183f265..28b1e59 100644 --- a/build.zig +++ b/build.zig @@ -40,6 +40,7 @@ pub fn build(b: *std.Build) void { .target = target, .optimize = optimize, }); + l0_mod.addImport("time", time_mod); const ipc_mod = b.createModule(.{ .root_source_file = b.path("core/l0-transport/ipc/client.zig"), .target = target, @@ -186,6 +187,8 @@ pub fn build(b: *std.Build) void { }); // SoulKey needs PQXDH for deterministic generation l1_soulkey_mod.addImport("pqxdh", l1_pqxdh_mod); + // Ensure l1_mod uses SoulKey + l1_mod.addImport("soulkey", l1_soulkey_mod); const l1_entropy_mod = b.createModule(.{ .root_source_file = b.path("core/l1-identity/entropy.zig"), @@ -219,6 +222,7 @@ pub fn build(b: *std.Build) void { .optimize = optimize, }); l1_mod.addImport("slash", l1_slash_mod); + l1_mod.addImport("time", time_mod); const l0_quarantine_mod = b.createModule(.{ .root_source_file = b.path("core/l0-transport/quarantine.zig"), @@ -238,6 +242,8 @@ pub fn build(b: *std.Build) void { }); // trust_graph needs crypto types l1_trust_graph_mod.addImport("crypto", l1_mod); + // l1_mod needs trust_graph for re-export + l1_mod.addImport("trust_graph", l1_trust_graph_mod); // ======================================================================== // L1 Proof of Path Module (PoP) @@ -264,6 +270,8 @@ pub fn build(b: *std.Build) void { l1_qvl_mod.addImport("proof_of_path", l1_pop_mod); l1_qvl_mod.addImport("time", time_mod); l1_qvl_mod.addImport("l0_transport", l0_mod); + // Also add qvl to l1_mod for re-export + l1_mod.addImport("qvl", l1_qvl_mod); // Note: libmdbx linking removed - using stub implementation for now // TODO: Add real libmdbx when available on build system @@ -277,6 +285,7 @@ pub fn build(b: *std.Build) void { l1_qvl_ffi_mod.addImport("slash", l1_slash_mod); l1_qvl_ffi_mod.addImport("time", time_mod); l1_qvl_ffi_mod.addImport("trust_graph", l1_trust_graph_mod); + l1_qvl_ffi_mod.addImport("proof_of_path", l1_pop_mod); // QVL FFI static library (for Rust L2 Membrane Agent) const qvl_ffi_lib = b.addLibrary(.{ @@ -561,6 +570,27 @@ pub fn build(b: *std.Build) void { test_step.dependOn(&run_png_tests.step); test_step.dependOn(&run_transport_skins_tests.step); + // ======================================================================== + // M0 BDD Feature Tests + // ======================================================================== + const bdd_tests_mod = b.createModule(.{ + .root_source_file = b.path("features/bdd_tests.zig"), + .target = target, + .optimize = optimize, + }); + bdd_tests_mod.addImport("l0_transport", l0_mod); + bdd_tests_mod.addImport("step_definitions", b.createModule(.{ + .root_source_file = b.path("features/step_definitions/lwf_frame_steps.zig"), + .target = target, + .optimize = optimize, + })); + + const bdd_tests = b.addTest(.{ + .root_module = bdd_tests_mod, + }); + const run_bdd_tests = b.addRunArtifact(bdd_tests); + test_step.dependOn(&run_bdd_tests.step); + // ======================================================================== // Examples // ======================================================================== @@ -635,7 +665,6 @@ pub fn build(b: *std.Build) void { capsule_mod.addImport("relay", relay_mod); capsule_mod.addImport("quarantine", l0_quarantine_mod); capsule_mod.addImport("policy", l2_policy_mod); - capsule_mod.addImport("soulkey", l1_soulkey_mod); capsule_mod.addImport("vaxis", vaxis_mod); capsule_mod.addImport("control", capsule_control_mod); diff --git a/capsule-core/src/federation.zig b/capsule-core/src/federation.zig index e9226dd..0448bee 100644 --- a/capsule-core/src/federation.zig +++ b/capsule-core/src/federation.zig @@ -4,7 +4,7 @@ const std = @import("std"); const net = std.net; const l0_transport = @import("l0_transport"); -const lwf = l0_transport.lwf; +const lwf = l0_transport; pub const VERSION: u32 = 2; pub const SERVICE_TYPE: u16 = lwf.LWFHeader.ServiceType.IDENTITY_SIGNAL; diff --git a/capsule-core/src/node.zig b/capsule-core/src/node.zig index d9cb2ec..93fd214 100644 --- a/capsule-core/src/node.zig +++ b/capsule-core/src/node.zig @@ -4,8 +4,9 @@ const std = @import("std"); const config_mod = @import("config.zig"); const l0_transport = @import("l0_transport"); +const utcp_mod = @import("utcp"); const l1_identity = @import("l1_identity"); -const l2_membrane = @import("l2_membrane"); +const policy_mod = @import("policy"); const discovery_mod = @import("discovery.zig"); const peer_table_mod = @import("peer_table.zig"); @@ -17,13 +18,13 @@ const circuit_mod = @import("circuit.zig"); const relay_service_mod = @import("relay_service.zig"); const NodeConfig = config_mod.NodeConfig; -const UTCP = l0_transport.utcp.UTCP; +const UTCP = utcp_mod.UTCP; const SoulKey = l1_identity.soulkey.SoulKey; const RiskGraph = l1_identity.qvl.types.RiskGraph; const DhtService = l0_transport.dht.DhtService; const Gateway = l0_transport.gateway.Gateway; const Quarantine = l0_transport.quarantine; -const PolicyEngine = l2_membrane.PolicyEngine; +const PolicyEngine = policy_mod.PolicyEngine; const DiscoveryService = discovery_mod.DiscoveryService; const PeerTable = peer_table_mod.PeerTable; const PeerSession = fed.PeerSession; @@ -243,7 +244,7 @@ pub const CapsuleNode = struct { self.allocator.destroy(self); } - fn processFrame(self: *CapsuleNode, frame: l0_transport.lwf.LWFFrame, sender: std.net.Address) void { + fn processFrame(self: *CapsuleNode, frame: l0_transport.LWFFrame, sender: std.net.Address) void { var f = frame; defer f.deinit(self.allocator); @@ -255,7 +256,7 @@ pub const CapsuleNode = struct { } switch (f.header.service_type) { - l0_transport.lwf.LWFHeader.ServiceType.RELAY_FORWARD => { + l0_transport.LWFHeader.ServiceType.RELAY_FORWARD => { if (self.relay_service) |*rs| { // Unwrap (Unlocked) // Unwrap (Locked - protects Sessions Map) @@ -284,10 +285,10 @@ pub const CapsuleNode = struct { self.state_mutex.unlock(); if (next_remote) |remote| { - var relay_frame = l0_transport.lwf.LWFFrame.init(self.allocator, next_hop_data.payload.len) catch return; + var relay_frame = l0_transport.LWFFrame.init(self.allocator, next_hop_data.payload.len) catch return; defer relay_frame.deinit(self.allocator); @memcpy(relay_frame.payload, next_hop_data.payload); - relay_frame.header.service_type = l0_transport.lwf.LWFHeader.ServiceType.RELAY_FORWARD; + relay_frame.header.service_type = l0_transport.LWFHeader.ServiceType.RELAY_FORWARD; self.utcp.sendFrame(remote.address, &relay_frame, self.allocator) catch |err| { std.log.warn("Relay Send Error: {}", .{err}); @@ -478,7 +479,7 @@ pub const CapsuleNode = struct { }; } - fn handleFederationMessage(self: *CapsuleNode, sender: std.net.Address, frame: l0_transport.lwf.LWFFrame) !void { + fn handleFederationMessage(self: *CapsuleNode, sender: std.net.Address, frame: l0_transport.LWFFrame) !void { var fbs = std.io.fixedBufferStream(frame.payload); const msg = fed.FederationMessage.decode(fbs.reader(), self.allocator) catch |err| { std.log.warn("Failed to decode federation message from {f}: {}", .{ sender, err }); @@ -740,10 +741,10 @@ pub const CapsuleNode = struct { const encoded = try packet.encode(self.allocator); defer self.allocator.free(encoded); - var frame = try l0_transport.lwf.LWFFrame.init(self.allocator, encoded.len); + var frame = try l0_transport.LWFFrame.init(self.allocator, encoded.len); defer frame.deinit(self.allocator); @memcpy(frame.payload, encoded); - frame.header.service_type = l0_transport.lwf.LWFHeader.ServiceType.RELAY_FORWARD; + frame.header.service_type = l0_transport.LWFHeader.ServiceType.RELAY_FORWARD; try self.utcp.sendFrame(first_hop, &frame, self.allocator); response = .{ .Ok = "Packet sent via Relay" }; @@ -965,7 +966,7 @@ pub const CapsuleNode = struct { try msg.encode(fbs.writer()); const payload = fbs.getWritten(); - var frame = try l0_transport.lwf.LWFFrame.init(self.allocator, payload.len); + var frame = try l0_transport.LWFFrame.init(self.allocator, payload.len); defer frame.deinit(self.allocator); frame.header.service_type = fed.SERVICE_TYPE; @@ -997,7 +998,7 @@ pub const CapsuleNode = struct { const payload = fbs.getWritten(); // Wrap in LWF - var frame = try l0_transport.lwf.LWFFrame.init(self.allocator, payload.len); + var frame = try l0_transport.LWFFrame.init(self.allocator, payload.len); defer frame.deinit(self.allocator); frame.header.service_type = fed.SERVICE_TYPE; diff --git a/core/l0-transport/mod.zig b/core/l0-transport/mod.zig index fbd87c9..94dc1ad 100644 --- a/core/l0-transport/mod.zig +++ b/core/l0-transport/mod.zig @@ -15,7 +15,7 @@ pub const LWFFlags = @import("lwf.zig").LWFFlags; pub const FrameClass = @import("lwf.zig").FrameClass; // Re-export Time primitives -pub const time = @import("time.zig"); +pub const time = @import("time"); // Note: UTCP is available as a separate module, not re-exported here // to avoid circular module dependencies (utcp needs lwf as module import) diff --git a/core/l1-identity/did.zig b/core/l1-identity/did.zig index d28f5cd..e7a784c 100644 --- a/core/l1-identity/did.zig +++ b/core/l1-identity/did.zig @@ -19,7 +19,7 @@ const std = @import("std"); const crypto = std.crypto; -const pqxdh = @import("pqxdh.zig"); +const pqxdh = @import("pqxdh"); // ============================================================================ // Constants diff --git a/core/l1-identity/mod.zig b/core/l1-identity/mod.zig index 01327cf..c387bae 100644 --- a/core/l1-identity/mod.zig +++ b/core/l1-identity/mod.zig @@ -2,20 +2,17 @@ const std = @import("std"); // Re-export Identity modules pub const did = @import("did.zig"); -pub const soulkey = @import("soulkey.zig"); -pub const qvl = @import("qvl.zig"); -pub const qvl_ffi = @import("qvl_ffi.zig"); +pub const soulkey = @import("soulkey"); +pub const qvl = @import("qvl"); +// Note: qvl_ffi is intentionally NOT exported here - built as separate library pub const entropy = @import("entropy.zig"); pub const crypto = @import("crypto.zig"); pub const argon2 = @import("argon2.zig"); -pub const pqxdh = @import("pqxdh.zig"); +pub const pqxdh = @import("pqxdh"); pub const prekey = @import("prekey.zig"); -pub const slash = @import("slash.zig"); -pub const trust_graph = @import("trust_graph.zig"); -pub const proof_of_path = @import("proof_of_path.zig"); - -// Note: qvl_ffi is intentionally NOT exported here to avoid circular dependency -// qvl_ffi is built as a separate library and imports from this module +pub const slash = @import("slash"); +pub const trust_graph = @import("trust_graph"); +pub const proof_of_path = @import("proof_of_path"); test { std.testing.refAllDecls(@This()); diff --git a/core/l1-identity/prekey.zig b/core/l1-identity/prekey.zig index 64d74e5..29dd500 100644 --- a/core/l1-identity/prekey.zig +++ b/core/l1-identity/prekey.zig @@ -11,7 +11,7 @@ const std = @import("std"); const crypto = std.crypto; -const pqxdh = @import("pqxdh.zig"); +const pqxdh = @import("pqxdh"); // ============================================================================ // Constants (Prekey Validity Periods) diff --git a/core/l1-identity/proof_of_path.zig b/core/l1-identity/proof_of_path.zig index be4eb25..6b89869 100644 --- a/core/l1-identity/proof_of_path.zig +++ b/core/l1-identity/proof_of_path.zig @@ -16,9 +16,9 @@ //! ] const std = @import("std"); -const trust_graph = @import("trust_graph.zig"); +const trust_graph = @import("trust_graph"); const time = @import("time"); -const soulkey = @import("soulkey.zig"); +const soulkey = @import("soulkey"); pub const PathVerdict = enum { /// Path is valid and active diff --git a/core/l1-identity/qvl/pop_integration.zig b/core/l1-identity/qvl/pop_integration.zig index ab3c465..e90594e 100644 --- a/core/l1-identity/qvl/pop_integration.zig +++ b/core/l1-identity/qvl/pop_integration.zig @@ -11,9 +11,9 @@ const std = @import("std"); const types = @import("types.zig"); const pathfinding = @import("pathfinding.zig"); -// Import proof_of_path relative from qvl directory -const pop = @import("../proof_of_path.zig"); -const trust_graph = @import("../trust_graph.zig"); +// Import proof_of_path and trust_graph as modules +const pop = @import("proof_of_path"); +const trust_graph = @import("trust_graph"); const NodeId = types.NodeId; const RiskGraph = types.RiskGraph; diff --git a/core/l1-identity/qvl_ffi.zig b/core/l1-identity/qvl_ffi.zig index a279a76..f5bdcf2 100644 --- a/core/l1-identity/qvl_ffi.zig +++ b/core/l1-identity/qvl_ffi.zig @@ -10,11 +10,10 @@ const std = @import("std"); const time = @import("time"); - -const qvl = @import("qvl.zig"); -const pop_mod = @import("proof_of_path.zig"); -const trust_graph = @import("trust_graph.zig"); -const slash = @import("slash.zig"); +const qvl = @import("qvl"); +const pop_mod = @import("proof_of_path"); +const trust_graph = @import("trust_graph"); +const slash = @import("slash"); const RiskGraph = qvl.types.RiskGraph; const RiskEdge = qvl.types.RiskEdge; diff --git a/core/l1-identity/trust_graph.zig b/core/l1-identity/trust_graph.zig index 174d429..e5f3d70 100644 --- a/core/l1-identity/trust_graph.zig +++ b/core/l1-identity/trust_graph.zig @@ -12,8 +12,8 @@ //! Memory budget: 100K nodes = 400KB (vs 6.4MB with raw DIDs) const std = @import("std"); -const soulkey = @import("soulkey.zig"); -const crypto = @import("crypto.zig"); +const soulkey = @import("soulkey"); +const crypto = @import("crypto"); /// Trust visibility levels (privacy control) /// Per RFC-0120 S4.3.1: Alice never broadcasts her full Trust DAG