milestone 27: diagnostics — operational failures land in one curated log, resolved history purgeable
Gates / frontend (push) Successful in 1m33s
Gates / test (push) Successful in 1m48s
Gates / test-aarch64 (push) Successful in 7m10s
Gates / package (push) Successful in 5m31s
Gates / container (push) Successful in 15s
CI / gates (push) Successful in 14m51s

This commit is contained in:
2026-08-20 20:05:59 +02:00
parent 3dd8214ef2
commit 037f209179
50 changed files with 8608 additions and 102 deletions
+12 -1
View File
@@ -36,6 +36,7 @@ const auth = @import("handlers/auth.zig");
const blocklists = @import("handlers/blocklists.zig");
const certs = @import("handlers/certs.zig");
const clients = @import("handlers/clients.zig");
const diagnostics = @import("handlers/diagnostics.zig");
const groups = @import("handlers/groups.zig");
const health = @import("handlers/health.zig");
const live = @import("handlers/live.zig");
@@ -71,6 +72,14 @@ pub const table: []const router.RouteInfo = &.{
.{ .method = .GET, .pattern = "/api/lookup", .auth = .session, .policy = .read, .handler = lookup.handle },
.{ .method = .GET, .pattern = "/api/upstream/health", .auth = .session, .policy = .read, .handler = upstream_health.handle },
// Diagnostics: the operational event log (milestone 27). The two purges are
// `runtime_action` — the event log is runtime state no configuration file
// declares, so file authority has nothing to say about deleting from it.
.{ .method = .GET, .pattern = "/api/diagnostics", .auth = .session, .policy = .read, .handler = diagnostics.list },
.{ .method = .DELETE, .pattern = "/api/diagnostics", .auth = .session, .policy = .runtime_action, .handler = diagnostics.purgeAll },
.{ .method = .GET, .pattern = "/api/diagnostics/{id}", .auth = .session, .policy = .read, .handler = diagnostics.get },
.{ .method = .DELETE, .pattern = "/api/diagnostics/{id}", .auth = .session, .policy = .runtime_action, .handler = diagnostics.purge },
// Groups.
.{ .method = .GET, .pattern = "/api/groups", .auth = .session, .policy = .read, .handler = groups.list },
.{ .method = .POST, .pattern = "/api/groups", .auth = .session, .policy = .config_write, .handler = groups.create },
@@ -143,7 +152,7 @@ const std = @import("std");
const testing = std.testing;
test "the table carries every endpoint of the milestone" {
try testing.expectEqual(@as(usize, 56), table.len);
try testing.expectEqual(@as(usize, 60), table.len);
}
test "no two entries claim the same method and pattern" {
@@ -231,6 +240,8 @@ test "the runtime actions are exactly ruling 7's list" {
"POST /api/auth/login",
"POST /api/auth/logout",
"POST /api/blocklists/update",
"DELETE /api/diagnostics",
"DELETE /api/diagnostics/{id}",
"DELETE /api/clients/{id}",
"POST /api/pause",
"POST /api/certs/reload",