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
11 changes: 9 additions & 2 deletions crates/iris-agentic-dev-bin/src/cmd/compile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -185,13 +185,20 @@ fn compile_result_to_json(r: &CompileResult, target: &str, namespace: &str) -> s
.iter()
.map(|e| serde_json::json!({"severity":"error","text":e}))
.collect();
serde_json::json!({
let mut out = serde_json::json!({
"success": r.success(),
"target": target,
"namespace": namespace,
"errors": errors,
"console": r.console,
})
});
iris_agentic_dev_core::tools::note_error_undercount(
&mut out,
r.detected_error_count(),
r.errors.len(),
"console",
);
out
}

fn output_result(result: &serde_json::Value, format: &str) {
Expand Down
29 changes: 10 additions & 19 deletions crates/iris-agentic-dev-core/src/iris/connection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,13 @@ impl CompileResult {
pub fn success(&self) -> bool {
self.errors.is_empty()
}

/// IRIS's own `Detected N errors during compilation` count, when the console carried it.
/// Cross-check it against `errors.len()` before presenting this list as complete —
/// see [`crate::tools::detected_error_count`].
pub fn detected_error_count(&self) -> Option<usize> {
crate::tools::detected_error_count(self.console.iter().map(String::as_str))
}
}

impl IrisConnection {
Expand Down Expand Up @@ -902,25 +909,9 @@ impl IrisConnection {
.collect()
})
.unwrap_or_default();
let mut errors: Vec<String> = vec![];
if let Some(se) = body["status"]["errors"].as_array() {
for e in se {
if let Some(msg) = e["error"].as_str() {
errors.push(msg.to_string());
}
}
}
// Issue #80: same colon-vs-space prefix defect as iris_compile's own console loop,
// a second consumer away (iris_doc{mode:put, compile:true}.compile_errors, and
// iris_compile's local-source upload path). Shares the one parser so the two cannot
// drift apart again.
for line in &console {
if let Some(d) = crate::tools::parse_console_diag(line, "ERROR:", "ERROR ") {
if errors.iter().all(|e| !e.contains(&d.text)) {
errors.push(d.text);
}
}
}
// Issue #80: the console loop lived here, in iris_compile and in iris_doc, and the
// fix reached two of the three. One shared assembly now, so they cannot drift.
let errors = crate::tools::compile_error_list(&body, &console);
Ok(CompileResult { errors, console })
}

Expand Down
38 changes: 22 additions & 16 deletions crates/iris-agentic-dev-core/src/tools/doc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -859,22 +859,14 @@ async fn do_write(
.collect()
})
.unwrap_or_default();
let mut errs: Vec<String> = vec![];
if let Some(se) = body["status"]["errors"].as_array() {
for e in se {
if let Some(msg) = e["error"].as_str() {
errs.push(msg.to_string());
}
}
}
for line in &console {
if line.trim().starts_with("ERROR ") {
let msg = line.trim().to_string();
if errs.iter().all(|e| !e.contains(line.trim())) {
errs.push(msg);
}
}
}
// #80 was fixed in iris_compile and in `compile_document` and never reached
// HERE, the third copy of the same loop. This build prefixes per-method
// diagnostics with `ERROR:` (colon); matching only `ERROR ` (space) missed
// every one of them. Measured live on IRIS 2026.1 (Build 235U): a 3-method
// class with 3 undefined macros printed `Detected 13 errors` and this path
// reported ONE — `#5123 Unable to find entry point`, a cascade, while the
// macros that caused it never appeared.
let errs = crate::tools::compile_error_list(&body, &console);
(errs.is_empty(), errs, console)
}
};
Expand All @@ -895,6 +887,12 @@ async fn do_write(
"compile_errors": compile_errors,
"compile_console": compile_console,
});
crate::tools::note_error_undercount(
&mut payload,
crate::tools::detected_error_count(compile_console.iter().map(String::as_str)),
compile_errors.len(),
"compile_console",
);
note_compile_time_methods(&mut payload, &generators);
return crate::tools::envelope::fail_with("COMPILE_ERROR", &first, payload);
}
Expand All @@ -907,6 +905,14 @@ async fn do_write(
"compile_errors": compile_errors,
"compile_console": compile_console,
});
// Reached with compile_errors EMPTY. If IRIS still counted errors here, "compiled:
// true" is the undercount at its worst — a failed compile reported as a success.
crate::tools::note_error_undercount(
&mut payload,
crate::tools::detected_error_count(compile_console.iter().map(String::as_str)),
compile_errors.len(),
"compile_console",
);
note_compile_time_methods(&mut payload, &generators);
return ok_json(payload);
}
Expand Down
Loading
Loading