Skip to content

Commit 8bb9591

Browse files
committed
chore: automated sync of local changes
1 parent 5de835f commit 8bb9591

5 files changed

Lines changed: 163 additions & 39 deletions

File tree

cartridges/007-mcp/adapter/oo7_adapter.zig

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,9 @@ fn dispatchTool(
199199
};
200200
defer inv.deinit(allocator);
201201

202+
const cleaned_stderr = try stripKnownNoise(allocator, inv.stderr);
203+
defer if (cleaned_stderr.ptr != inv.stderr.ptr) allocator.free(cleaned_stderr);
204+
202205
var w = out.writer(allocator);
203206
try w.writeAll("{\"success\":");
204207
try w.writeAll(if (inv.exit_code == 0) "true" else "false");
@@ -207,11 +210,47 @@ fn dispatchTool(
207210
try w.writeAll(",\"stdout\":");
208211
try writeJsonString(w, inv.stdout);
209212
try w.writeAll(",\"stderr\":");
210-
try writeJsonString(w, inv.stderr);
213+
try writeJsonString(w, cleaned_stderr);
211214
try w.writeByte('}');
212215
return 200;
213216
}
214217

218+
fn isKnownNoiseLine(line: []const u8) bool {
219+
if (std.mem.eql(u8, line, "warning: profiles for the non root package will be ignored, specify profiles at the workspace root:")) {
220+
return true;
221+
}
222+
if (std.mem.startsWith(u8, line, "package:") and std.mem.indexOf(u8, line, "/linker/Cargo.toml") != null) {
223+
return true;
224+
}
225+
if (std.mem.startsWith(u8, line, "workspace:") and std.mem.indexOf(u8, line, "/Cargo.toml") != null) {
226+
return true;
227+
}
228+
return false;
229+
}
230+
231+
/// Strip repetitive low-signal Cargo workspace-profile warnings from stderr.
232+
/// Returns the original slice when no filtering was applied.
233+
fn stripKnownNoise(allocator: std.mem.Allocator, stderr: []const u8) ![]const u8 {
234+
if (stderr.len == 0) return stderr;
235+
236+
var out = std.ArrayList(u8).initCapacity(allocator, stderr.len) catch return stderr;
237+
defer out.deinit(allocator);
238+
239+
var changed = false;
240+
var line_it = std.mem.splitScalar(u8, stderr, '\n');
241+
while (line_it.next()) |line| {
242+
if (isKnownNoiseLine(line)) {
243+
changed = true;
244+
continue;
245+
}
246+
try out.appendSlice(allocator, line);
247+
try out.append(allocator, '\n');
248+
}
249+
250+
if (!changed) return stderr;
251+
return try out.toOwnedSlice(allocator);
252+
}
253+
215254
// ═══════════════════════════════════════════════════════════════════════
216255
// Main — HTTP server
217256
// ═══════════════════════════════════════════════════════════════════════

cartridges/007-mcp/ffi/oo7_mcp_ffi.zig

Lines changed: 117 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ pub const BIND_PORT: u16 = 1066;
3232

3333
/// Coord server URL — cartridge acts as a client during OnEnter/OnExit.
3434
pub const COORD_URL = "http://127.0.0.1:7745";
35+
pub const COORD_REGISTER_URL = COORD_URL ++ "/tools/coord_register";
3536

3637
pub const MAX_TOOL_NAME: usize = 48;
3738
pub const MAX_ARG_STRING: usize = 4096;
@@ -264,14 +265,17 @@ pub const EnterResult = struct {
264265
methodology_files: []const []const u8,
265266
memory_hits: []const []const u8,
266267
pub fn deinit(self: *EnterResult, allocator: std.mem.Allocator) void {
268+
for (self.methodology_files) |p| allocator.free(p);
267269
allocator.free(self.methodology_files);
270+
for (self.memory_hits) |p| allocator.free(p);
268271
allocator.free(self.memory_hits);
269272
}
270273
};
271274

272275
/// OnEnter: register as coord peer (soft-fail to Degraded), load 6a2,
273276
/// run memory auto-lift. Idempotent: re-calling from Registered or
274-
/// Degraded is a no-op that returns the cached peer_id.
277+
/// Degraded is a no-op that returns the cached peer_id. Re-entering
278+
/// after Deregistered starts a new registration attempt.
275279
///
276280
/// The adapter handles the HTTP framing; this function only does the
277281
/// state transition + the coord POST + the file-system reads.
@@ -283,18 +287,40 @@ pub fn onEnter(
283287
_ = session_hint; // surfaced in future; no state effect today
284288

285289
const cur = state();
286-
if (cur == .registered or cur == .degraded) {
290+
if (cur == .registered) {
287291
// Idempotent — return the existing identity and a re-read methodology pack.
288292
const methodology = try readMethodologyPack(allocator, worktree);
289293
const memory = try memoryAutolift(allocator, worktree);
290294
return .{
291295
.peer_id = peerId(),
292-
.coord_state = if (cur == .registered) "registered" else "degraded",
296+
.coord_state = "registered",
293297
.methodology_files = methodology,
294298
.memory_hits = memory,
295299
};
296300
}
297-
if (cur != .fresh) return error.BadState;
301+
if (cur == .degraded) {
302+
// Retry registration so degraded sessions can self-heal when
303+
// local-coord-mcp becomes reachable again.
304+
const upgraded = coordRegister(allocator) catch false;
305+
if (upgraded) {
306+
setState(.registered);
307+
} else if (g_peer_id_len == 0) {
308+
const local_id = "claude-0000@007-lang-local";
309+
@memcpy(g_peer_id_buf[0..local_id.len], local_id);
310+
g_peer_id_len = local_id.len;
311+
g_coord_token_len = 0;
312+
}
313+
314+
const methodology = try readMethodologyPack(allocator, worktree);
315+
const memory = try memoryAutolift(allocator, worktree);
316+
return .{
317+
.peer_id = peerId(),
318+
.coord_state = if (state() == .registered) "registered" else "degraded",
319+
.methodology_files = methodology,
320+
.memory_hits = memory,
321+
};
322+
}
323+
if (cur != .fresh and cur != .deregistered) return error.BadState;
298324

299325
// Try coord_register. Soft-fail to Degraded on any error.
300326
const registered = coordRegister(allocator) catch |e| blk: {
@@ -310,6 +336,7 @@ pub fn onEnter(
310336
const local_id = "claude-0000@007-lang-local";
311337
@memcpy(g_peer_id_buf[0..local_id.len], local_id);
312338
g_peer_id_len = local_id.len;
339+
g_coord_token_len = 0;
313340
}
314341

315342
const methodology = try readMethodologyPack(allocator, worktree);
@@ -327,6 +354,7 @@ pub const ExitResult = struct {
327354
drift_findings: []const []const u8,
328355
coord_state: []const u8,
329356
pub fn deinit(self: *ExitResult, allocator: std.mem.Allocator) void {
357+
for (self.drift_findings) |p| allocator.free(p);
330358
allocator.free(self.drift_findings);
331359
}
332360
};
@@ -343,12 +371,12 @@ pub fn onExit(
343371

344372
const findings = try driftCheck(allocator, worktree);
345373

346-
if (cur == .registered) {
347-
// Best-effort coord deregister; failure is logged but not fatal.
348-
coordDeregister(allocator) catch |e| {
374+
// Best-effort coord teardown; failure is non-fatal.
375+
coordDeregister(allocator) catch |e| {
376+
if (cur == .registered) {
349377
std.log.warn("007-mcp: coord_deregister failed ({}); proceeding to Deregistered", .{e});
350-
};
351-
}
378+
}
379+
};
352380

353381
setState(.deregistered);
354382
return .{
@@ -384,11 +412,19 @@ fn readMethodologyPack(
384412
// explicit sentinel like "MISSING::<path>".
385413
var path_buf: [std.fs.max_path_bytes]u8 = undefined;
386414
const full = std.fmt.bufPrint(&path_buf, "{s}/{s}", .{ worktree, rel }) catch rel;
387-
std.fs.accessAbsolute(full, .{}) catch {
388-
const missing = try std.fmt.allocPrint(allocator, "MISSING::{s}", .{rel});
389-
out[i] = missing;
390-
continue;
391-
};
415+
if (std.fs.path.isAbsolute(full)) {
416+
std.fs.accessAbsolute(full, .{}) catch {
417+
const missing = try std.fmt.allocPrint(allocator, "MISSING::{s}", .{rel});
418+
out[i] = missing;
419+
continue;
420+
};
421+
} else {
422+
std.fs.cwd().access(full, .{}) catch {
423+
const missing = try std.fmt.allocPrint(allocator, "MISSING::{s}", .{rel});
424+
out[i] = missing;
425+
continue;
426+
};
427+
}
392428
out[i] = try allocator.dupe(u8, rel);
393429
}
394430
return out;
@@ -427,6 +463,13 @@ pub const TAG_MAP_PATHS = [_][]const u8{
427463
"/var/mnt/eclipse/repos/boj-server/cartridges/007-mcp/schemas/memory-tag-map.a2ml",
428464
};
429465

466+
fn openMaybeAbsolute(path: []const u8) !std.fs.File {
467+
if (std.fs.path.isAbsolute(path)) {
468+
return try std.fs.openFileAbsolute(path, .{});
469+
}
470+
return try std.fs.cwd().openFile(path, .{});
471+
}
472+
430473
/// Read the tag map from disk (first candidate that exists wins).
431474
/// Caller owns the returned slice.
432475
fn readTagMap(allocator: std.mem.Allocator, worktree: []const u8) ![]u8 {
@@ -436,7 +479,7 @@ fn readTagMap(allocator: std.mem.Allocator, worktree: []const u8) ![]u8 {
436479
rel
437480
else
438481
std.fmt.bufPrint(&path_buf, "{s}/{s}", .{ worktree, rel }) catch continue;
439-
const file = std.fs.openFileAbsolute(full, .{}) catch continue;
482+
const file = openMaybeAbsolute(full) catch continue;
440483
defer file.close();
441484
const stat = try file.stat();
442485
const buf = try allocator.alloc(u8, stat.size);
@@ -570,24 +613,57 @@ fn driftCheck(
570613

571614
// ─── Coord client ──────────────────────────────────────────────────────
572615

573-
/// POST coord_register to local-coord-mcp. Returns true on success.
574-
/// Current implementation returns false (Degraded) when the socket isn't
575-
/// reachable — the adapter layer owns the actual HTTP write and token
576-
/// parse. Kept as a hookable function here so tests can stub it.
616+
/// POST coord_register to local-coord-mcp.
617+
/// Returns true only when an HTTP 200 response carries
618+
/// {"success":true,"peer_id":"...","token":"..."}.
577619
fn coordRegister(allocator: std.mem.Allocator) !bool {
578-
_ = allocator;
579-
// Probe TCP connect to 127.0.0.1:7745; any failure → Degraded.
580-
const addr = std.net.Address.initIp4(BIND_ADDR, 7745);
581-
const sock = std.net.tcpConnectToAddress(addr) catch return false;
582-
sock.close();
583-
// Real register happens in the adapter layer where the HTTP client
584-
// is wired; here we only certify reachability.
585-
const synth = "claude-007a@007-lang";
586-
@memcpy(g_peer_id_buf[0..synth.len], synth);
587-
g_peer_id_len = synth.len;
588-
const tok = "0000000000000000000000000000000000000000000000000000000000000000";
589-
@memcpy(g_coord_token_buf[0..64], tok);
590-
g_coord_token_len = 64;
620+
g_peer_id_len = 0;
621+
g_coord_token_len = 0;
622+
623+
var client = std.http.Client{ .allocator = allocator };
624+
defer client.deinit();
625+
626+
const uri = std.Uri.parse(COORD_REGISTER_URL) catch return false;
627+
const payload = "{\"client_kind\":\"claude\",\"context\":\"007-lang\"}";
628+
629+
var headers_buf: [2]std.http.Header = .{
630+
.{ .name = "Content-Type", .value = "application/json" },
631+
.{ .name = "User-Agent", .value = "007-mcp/0.1 coord-register" },
632+
};
633+
634+
var aw: std.Io.Writer.Allocating = .init(allocator);
635+
defer aw.deinit();
636+
637+
const fetch_result = client.fetch(.{
638+
.method = .POST,
639+
.location = .{ .uri = uri },
640+
.extra_headers = &headers_buf,
641+
.payload = payload,
642+
.response_writer = &aw.writer,
643+
}) catch return false;
644+
645+
if (@intFromEnum(fetch_result.status) != 200) return false;
646+
647+
const body = aw.writer.buffered();
648+
const parsed = std.json.parseFromSlice(std.json.Value, allocator, body, .{}) catch return false;
649+
defer parsed.deinit();
650+
651+
const obj = if (parsed.value == .object) parsed.value.object else return false;
652+
const ok_val = obj.get("success") orelse return false;
653+
if (ok_val != .bool or !ok_val.bool) return false;
654+
const peer_id_val = obj.get("peer_id") orelse return false;
655+
const token_val = obj.get("token") orelse return false;
656+
if (peer_id_val != .string or token_val != .string) return false;
657+
658+
const peer_id = peer_id_val.string;
659+
const token = token_val.string;
660+
if (peer_id.len == 0 or peer_id.len > g_peer_id_buf.len) return false;
661+
if (token.len == 0 or token.len > g_coord_token_buf.len) return false;
662+
663+
@memcpy(g_peer_id_buf[0..peer_id.len], peer_id);
664+
g_peer_id_len = peer_id.len;
665+
@memcpy(g_coord_token_buf[0..token.len], token);
666+
g_coord_token_len = token.len;
591667
return true;
592668
}
593669

@@ -624,6 +700,15 @@ test "lifecycle state round-trip" {
624700
setState(.fresh); // reset for other tests
625701
}
626702

703+
test "onEnter accepts re-entry from deregistered state" {
704+
setState(.deregistered);
705+
var enter = try onEnter(std.testing.allocator, ".", "");
706+
defer enter.deinit(std.testing.allocator);
707+
708+
try std.testing.expect(enter.peer_id.len > 0);
709+
try std.testing.expect(std.mem.eql(u8, enter.coord_state, "registered") or std.mem.eql(u8, enter.coord_state, "degraded"));
710+
}
711+
627712
test "matchMemories picks memories from matching tag blocks only" {
628713
const map =
629714
\\;; comment line

proofs/canonical-proof-suite/M1.sidecar.a2ml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,6 @@
1111
(expected-symbol "infinitudeOfPrimes")
1212
(semantic-check "verified")
1313
(status "passing")
14-
(elapsed-ms 3422)
14+
(elapsed-ms 3346)
1515
(banned-constructs-found "")
16-
(last-checked-utc "2026-04-19T02:48:09Z"))
16+
(last-checked-utc "2026-04-19T18:32:17Z"))

proofs/canonical-proof-suite/M2.sidecar.a2ml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,6 @@
1111
(expected-symbol "lagrangeTheorem")
1212
(semantic-check "verified")
1313
(status "passing")
14-
(elapsed-ms 1846)
14+
(elapsed-ms 1482)
1515
(banned-constructs-found "")
16-
(last-checked-utc "2026-04-19T02:48:11Z"))
16+
(last-checked-utc "2026-04-19T18:32:18Z"))

proofs/canonical-proof-suite/M3.sidecar.a2ml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,6 @@
1111
(expected-symbol "intermediate_value_theorem")
1212
(semantic-check "verified")
1313
(status "passing")
14-
(elapsed-ms 1479)
14+
(elapsed-ms 1056)
1515
(banned-constructs-found "")
16-
(last-checked-utc "2026-04-19T02:48:12Z"))
16+
(last-checked-utc "2026-04-19T18:32:19Z"))

0 commit comments

Comments
 (0)