docs(error_wire): note stale_cursor convention (fb-34)

stale_cursor is built by cursor::decode, not classify. Test
locks the invariant.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
th-kim0823
2026-05-09 17:50:39 +09:00
parent ebbc3a46ae
commit aabe66f5e2

View File

@@ -11,6 +11,10 @@ use serde_json::{Value, json};
use crate::error_signal::{ConfigInvalid, LlmError, NotIndexed};
// p9-fb-34: `stale_cursor` is constructed directly by `cursor::decode`
// instead of routed through `classify`. Keep that contract — adding a
// classify branch would create two sources of truth for the same code.
/// Wire schema id for [`ErrorV1`]. Single source of truth — kebab-cli
/// + kebab-mcp use this via `kebab_app::ERROR_V1_ID`.
pub const ERROR_V1_ID: &str = "error.v1";
@@ -197,4 +201,16 @@ mod tests {
let v1 = classify(&err, false);
assert_eq!(v1.code, "io_error");
}
#[test]
fn stale_cursor_is_not_routed_through_classify() {
use anyhow::anyhow;
let err: anyhow::Error = anyhow!("stale_cursor: rev mismatch");
let v1 = classify(&err, false);
// p9-fb-34: stale_cursor is constructed directly by cursor::decode
// (single source of truth). classify routes anyhow strings to the
// generic "unknown" code. This test pins that contract — adding a
// classify branch for stale_cursor would create two sources.
assert_ne!(v1.code, "stale_cursor", "classify must not produce stale_cursor — cursor::decode is sole source");
}
}