🏗️ refactor(kebab-app): promote error_classify → kebab-app::error_wire (fb-30 prep)

fb-30 의 새 crate `kebab-mcp` 가 동일 classify 모듈 사용 — UI crate 끼리
import 는 facade rule 위반이므로 kebab-app 으로 promotion. fb-27 commit
c91228e 의 코드 그대로 이전 (struct + classify + classify_llm + 7 unit
test). reqwest dev-dep 도 함께 이동.

kebab-cli 는 `kebab_app::ErrorV1` / `kebab_app::classify` 로 import 경로
1줄 변경 + wire.rs 의 `&crate::error_classify::ErrorV1` 1줄 교체. 동작
무영향.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
th-kim0823
2026-05-07 15:13:28 +09:00
parent 65cfaf7c75
commit 1f53930234
7 changed files with 12 additions and 11 deletions

2
Cargo.lock generated
View File

@@ -3516,6 +3516,7 @@ dependencies = [
"kebab-store-vector",
"lopdf",
"lru",
"reqwest",
"rusqlite",
"serde",
"serde_json",
@@ -3558,7 +3559,6 @@ dependencies = [
"kebab-core",
"kebab-eval",
"kebab-tui",
"reqwest",
"serde",
"serde_json",
"tempfile",

View File

@@ -64,3 +64,6 @@ image = { version = "0.25", default-features = false, features =
# to the same major (0.32) so byte output is identical between the two
# fixture surfaces.
lopdf = "0.32"
# error_wire::tests::llm_unreachable_classifies_to_model_unreachable needs a real
# reqwest::Error (private constructor) — built from a connect-refused call.
reqwest = { version = "0.12", default-features = false, features = ["blocking", "rustls-tls"] }

View File

@@ -9,7 +9,7 @@
use serde::{Deserialize, Serialize};
use serde_json::{Value, json};
use kebab_app::error_signal::{ConfigInvalid, LlmError, NotIndexed};
use crate::error_signal::{ConfigInvalid, LlmError, NotIndexed};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ErrorV1 {

View File

@@ -57,6 +57,7 @@ use kebab_source_fs::FsSourceConnector;
mod app;
pub mod doctor_signal;
pub mod error_signal;
pub mod error_wire;
pub mod ingest_progress;
pub mod logging;
pub mod reset;
@@ -65,6 +66,7 @@ pub mod schema;
pub use app::App;
pub use ingest_progress::{AggregateCounts, IngestEvent, render_skipped_breakdown};
pub use reset::{ResetReport, ResetScope};
pub use error_wire::{ErrorV1, classify};
pub use schema::{Capabilities, Models, SCHEMA_V1_ID, SchemaV1, Stats, WireBlock, schema_with_config};
/// p9-fb-25: sentinel for files without an extension in

View File

@@ -44,6 +44,3 @@ ctrlc = "3"
[dev-dependencies]
tempfile = { workspace = true }
# llm_unreachable_classifies_to_model_unreachable test needs a real
# reqwest::Error (private constructor) — built from a connect-refused call.
reqwest = { version = "0.12", default-features = false, features = ["blocking", "rustls-tls"] }

View File

@@ -9,7 +9,6 @@ use clap::{Parser, Subcommand};
use kebab_app::doctor_signal::{DoctorUnhealthy, NoHitSignal, RefusalSignal};
mod cancel;
mod error_classify;
mod progress;
mod wire;
@@ -282,7 +281,7 @@ fn main() -> ExitCode {
// caller); errors go to stderr.
if code != 1 {
if cli.json {
let v1 = error_classify::classify(&e, cli.verbose);
let v1 = kebab_app::classify(&e, cli.verbose);
let v = wire::wire_error_v1(&v1);
eprintln!("{}", serde_json::to_string(&v).unwrap_or_else(|_| {
"{\"schema_version\":\"error.v1\",\"code\":\"generic\",\"message\":\"serialize failed\"}".to_string()

View File

@@ -152,12 +152,12 @@ pub fn wire_schema(s: &kebab_app::SchemaV1) -> Value {
tag_object(v, kebab_app::SCHEMA_V1_ID)
}
/// Wrap an [`crate::error_classify::ErrorV1`] as `error.v1`.
/// Wrap an [`kebab_app::ErrorV1`] as `error.v1`.
///
/// Uses the simple `tag_object` pattern because `ErrorV1` is a
/// kebab-cli-local type that does NOT carry `schema_version` itself
/// type that does NOT carry `schema_version` itself
/// (kebab-core convention).
pub fn wire_error_v1(e: &crate::error_classify::ErrorV1) -> Value {
pub fn wire_error_v1(e: &kebab_app::ErrorV1) -> Value {
let v = serde_json::to_value(e).expect("ErrorV1 serializes");
tag_object(v, "error.v1")
}
@@ -262,7 +262,7 @@ mod tests {
#[test]
fn error_wrapper_tags_schema_version_and_emits_code() {
use crate::error_classify::ErrorV1;
use kebab_app::ErrorV1;
let err = ErrorV1 {
code: "config_invalid".to_string(),
message: "bad config".to_string(),