Skip to content

Commit 93f3afd

Browse files
Antigravity Agentclaude
andcommitted
feat(mu): MU Error Protocol — structured failure logging (#73)
- specs/tri/mu_error_protocol.tri: VIBEE spec, vibee gen + ast-check pass - src/tri/mu_error_protocol.zig: structured JSON error logging - ErrorCategory enum (9 categories) + auto-categorization - logError() → .trinity/mu/errors/{timestamp}.json - tri mu errors [--category X] [--limit N] - tri mu stats → category breakdown table - 7/7 unit tests pass, E2E verified with test data Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent a2e0df4 commit 93f3afd

3 files changed

Lines changed: 614 additions & 0 deletions

File tree

specs/tri/mu_error_protocol.tri

Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
# ═══════════════════════════════════════════════════════════════════════════════
2+
# VIBEE Specification — MU Error Protocol
3+
# ═══════════════════════════════════════════════════════════════════════════════
4+
# φ² + 1/φ² = 3 = TRINITY
5+
# Issue #73: Structured failure logging for Agent MU
6+
# ═══════════════════════════════════════════════════════════════════════════════
7+
8+
name: mu_error_protocol
9+
version: "1.0.0"
10+
language: zig
11+
module: mu_error_protocol
12+
13+
description: |
14+
MU Error Protocol — structured JSON logging of every pipeline failure.
15+
Each error → .trinity/mu/errors/{timestamp}.json.
16+
Queryable by category, with stats summaries.
17+
18+
# ═══════════════════════════════════════════════════════════════════════════════
19+
# TYPE SYSTEM
20+
# ═══════════════════════════════════════════════════════════════════════════════
21+
22+
types:
23+
ErrorCategory:
24+
variants:
25+
- type_mapping
26+
- undefined_identifier
27+
- syntax_error
28+
- format_error
29+
- import_error
30+
- memory_error
31+
- test_failure
32+
- gen_failure
33+
- unknown
34+
35+
MuError:
36+
fields:
37+
timestamp: String
38+
spec: String
39+
link: Int
40+
link_name: String
41+
error_category: ErrorCategory
42+
error_message: String
43+
error_line: Int
44+
generated_file: String
45+
fix_attempted: Bool
46+
fix_result: String
47+
48+
ErrorStats:
49+
fields:
50+
total_errors: Int
51+
category_counts: List(Int)
52+
has_last_error: Bool
53+
error_rate: Float
54+
55+
QueryFilter:
56+
fields:
57+
category_filter: String
58+
spec_filter: String
59+
limit: Int
60+
61+
# ═══════════════════════════════════════════════════════════════════════════════
62+
# BEHAVIORS
63+
# ═══════════════════════════════════════════════════════════════════════════════
64+
65+
behaviors:
66+
log_error:
67+
description: "Log a pipeline error to .trinity/mu/errors/"
68+
inputs:
69+
- error: MuError
70+
output: String
71+
steps:
72+
- Ensure .trinity/mu/errors/ directory exists
73+
- Generate filename from timestamp
74+
- Serialize MuError to JSON
75+
- Write to .trinity/mu/errors/{timestamp}.json
76+
- Return file path
77+
78+
query_errors:
79+
description: "Query errors with optional category filter"
80+
inputs:
81+
- filter: QueryFilter
82+
output: List(MuError)
83+
steps:
84+
- Scan .trinity/mu/errors/*.json
85+
- Parse each JSON file
86+
- Apply category filter if set
87+
- Apply spec filter if set
88+
- Return up to limit results
89+
90+
get_stats:
91+
description: "Get error statistics by category"
92+
inputs: []
93+
output: ErrorStats
94+
steps:
95+
- Scan all error files
96+
- Count by category
97+
- Find last error
98+
- Calculate error rate
99+
- Return ErrorStats
100+
101+
categorize_error:
102+
description: "Classify error message into ErrorCategory"
103+
inputs:
104+
- message: String
105+
output: ErrorCategory
106+
steps:
107+
- Check for type mapping keywords
108+
- Check for undefined identifier
109+
- Check for syntax patterns
110+
- Check for format issues
111+
- Default to unknown
112+
113+
run_mu_errors_command:
114+
description: "CLI: tri mu errors [--category X] [--limit N]"
115+
inputs:
116+
- args: List(String)
117+
output: Void
118+
steps:
119+
- Parse --category and --limit flags
120+
- Call query_errors with filter
121+
- Print results table
122+
123+
run_mu_stats_command:
124+
description: "CLI: tri mu stats"
125+
inputs: []
126+
output: Void
127+
steps:
128+
- Call get_stats
129+
- Print category breakdown table
130+
- Print V-formula with error rate
131+
132+
# ═══════════════════════════════════════════════════════════════════════════════
133+
# CONSTRAINTS
134+
# ═══════════════════════════════════════════════════════════════════════════════
135+
136+
constraints:
137+
- One JSON file per error (atomic writes)
138+
- Directory auto-created on first log
139+
- Maximum 10,000 error files (rotate oldest)
140+
- JSON must be valid and parseable
141+
- Category classification is best-effort
142+
143+
# ═══════════════════════════════════════════════════════════════════════════════
144+
# TESTS
145+
# ═══════════════════════════════════════════════════════════════════════════════
146+
147+
tests:
148+
- name: "categorize TYPE_MAPPING"
149+
input: {message: "use of undeclared identifier 'Int64'"}
150+
expected: {category: "type_mapping"}
151+
152+
- name: "categorize SYNTAX_ERROR"
153+
input: {message: "expected ';' after statement"}
154+
expected: {category: "syntax_error"}
155+
156+
- name: "categorize FORMAT_ERROR"
157+
input: {message: "formatting check failed"}
158+
expected: {category: "format_error"}
159+
160+
- name: "categorize UNKNOWN"
161+
input: {message: "something weird happened"}
162+
expected: {category: "unknown"}

src/tri/main.zig

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -510,12 +510,21 @@ pub fn main() !void {
510510
if (p.resolved) "RESOLVED" else "OPEN",
511511
});
512512
}
513+
} else if (std.mem.eql(u8, subcmd, "errors")) {
514+
const mu_proto = @import("mu_error_protocol.zig");
515+
const sub_args = if (cmd_args.len > 1) cmd_args[1..] else &[_][]const u8{};
516+
try mu_proto.runMuErrorsCommand(allocator, sub_args);
517+
} else if (std.mem.eql(u8, subcmd, "stats")) {
518+
const mu_proto = @import("mu_error_protocol.zig");
519+
try mu_proto.runMuStatsCommand(allocator);
513520
} else {
514521
std.debug.print(
515522
\\🧠 MU — Memory Unit
516523
\\Usage: tri mu <command>
517524
\\ status Show patterns + stats
518525
\\ patterns List all known patterns
526+
\\ errors Query logged errors (--category, --limit)
527+
\\ stats Error statistics by category
519528
\\ help Show this help
520529
\\
521530
, .{});

0 commit comments

Comments
 (0)