Finding
crate::notifications::TurnSummary::tool_calls (crates/zeph-core/src/notifications.rs:80) is documented as "Number of tool calls dispatched this turn" — a real per-turn counter. Its only production construction site hardcodes it to 0 with an untracked TODO:
// crates/zeph-core/src/agent/mod.rs:1350-1351
// TODO: wire turn_tool_calls counter once LifecycleState tracks it (Phase 2).
tool_calls: 0,
Currently this has no live user-visible effect (verified: neither build_notification_message nor fire_webhook's NtfyWebhookBody serialize tool_calls, and no ZEPH_TURN_TOOL_CALLS env var is inserted for turn_complete hooks — crates/zeph-core/src/agent/mod.rs:1379-1394), so the field is dead data today. But it is a pub field on a documented struct with a doc-test example showing a non-zero value (crates/zeph-core/src/notifications.rs:38, //! tool_calls: 2,), so any future consumer (a new webhook field, a new hook env var, or an external crate depending on zeph-core) will silently receive 0 regardless of actual tool usage. The TODO has no linked issue, so there is no tracked path to closing this gap.
Location
crates/zeph-core/src/agent/mod.rs:1350-1351 (hardcoded value + untracked TODO)
crates/zeph-core/src/notifications.rs:74-86 (struct + misleading doc comment/example)
Before
let summary = crate::notifications::TurnSummary {
duration_ms,
preview: self.last_assistant_preview(160),
// TODO: wire turn_tool_calls counter once LifecycleState tracks it (Phase 2).
tool_calls: 0,
llm_requests: self.runtime.lifecycle.turn_llm_requests,
exit_status: if is_error { ... } else { ... },
};
After
Either wire a real per-turn tool-call counter (mirroring how runtime.lifecycle.turn_llm_requests is already tracked and reset in begin_turn/incremented on each LLM round-trip) and pass it here, or — if that is out of scope for now — remove the field from TurnSummary until it is actually implemented, per the project's "no half-finished implementations" guidance. At minimum, replace the untracked // TODO: ... (Phase 2) with a comment linking a filed tracking issue.
Why
A public, documented struct field that always reports a wrong value (0) regardless of real tool activity is a misleading API contract — the doc comment and doc-test both imply real data. It currently causes no visible bug only because nothing downstream reads the field yet; the risk is that the next consumer (webhook payload extension, new hook env var) trusts the field and ships incorrect telemetry. Filed per CLAUDE.md's technical-debt-marker triage: TODOs must be either scheduled (issue-linked) or removed, not left to accumulate silently.
Read-only architecture audit — no code changes made, per rust-arch-analyst protocol.
Finding
crate::notifications::TurnSummary::tool_calls(crates/zeph-core/src/notifications.rs:80) is documented as "Number of tool calls dispatched this turn" — a real per-turn counter. Its only production construction site hardcodes it to0with an untracked TODO:Currently this has no live user-visible effect (verified: neither
build_notification_messagenorfire_webhook'sNtfyWebhookBodyserializetool_calls, and noZEPH_TURN_TOOL_CALLSenv var is inserted forturn_completehooks —crates/zeph-core/src/agent/mod.rs:1379-1394), so the field is dead data today. But it is apubfield on a documented struct with a doc-test example showing a non-zero value (crates/zeph-core/src/notifications.rs:38,//! tool_calls: 2,), so any future consumer (a new webhook field, a new hook env var, or an external crate depending onzeph-core) will silently receive0regardless of actual tool usage. The TODO has no linked issue, so there is no tracked path to closing this gap.Location
crates/zeph-core/src/agent/mod.rs:1350-1351(hardcoded value + untracked TODO)crates/zeph-core/src/notifications.rs:74-86(struct + misleading doc comment/example)Before
After
Either wire a real per-turn tool-call counter (mirroring how
runtime.lifecycle.turn_llm_requestsis already tracked and reset inbegin_turn/incremented on each LLM round-trip) and pass it here, or — if that is out of scope for now — remove the field fromTurnSummaryuntil it is actually implemented, per the project's "no half-finished implementations" guidance. At minimum, replace the untracked// TODO: ... (Phase 2)with a comment linking a filed tracking issue.Why
A public, documented struct field that always reports a wrong value (0) regardless of real tool activity is a misleading API contract — the doc comment and doc-test both imply real data. It currently causes no visible bug only because nothing downstream reads the field yet; the risk is that the next consumer (webhook payload extension, new hook env var) trusts the field and ships incorrect telemetry. Filed per CLAUDE.md's technical-debt-marker triage: TODOs must be either scheduled (issue-linked) or removed, not left to accumulate silently.
Read-only architecture audit — no code changes made, per rust-arch-analyst protocol.