# Observability should describe these boundaries

Useful traces distinguish model latency, admission wait, tool execution, approval wait, compaction, persistence, and user-input admission. A single run-duration counter cannot explain which layer was slow or whether “done” means model completion, tool completion, session settlement, or committed storage.

Pi provides a concrete example: an ordinary tool's duration measures `tool.execute`, excluding preflight and post-tool hooks. Its code-mode nested-call timer surrounds `ctx.executeTool`, which includes the nested pipeline. The numbers describe different intervals even within one harness. Compare like intervals before attributing a difference to performance. [Pi tool timing][p-timing], [pi nested-call timing][p-code-timing].

## Sidekick: visible does not always mean committed

Sidekick separates ephemeral text/progress events, persisted conversation messages, and durable turn outcomes. Its session reducer describes effects; the executor writes message rows into the caller's database transaction and can then broadcast them before that transaction commits. A user may therefore see an update that a later rollback removes from durable history. Atomic sequence numbers coordinate concurrent writers, but receiving a number is not proof of commit. Explicit deferred-broadcast paths provide a stronger acknowledgement boundary. [Effect execution][s-effects], [dispatch][s-dispatch]. Sidekick's source is private; these pinned links require repository access.

Native turn completion has a different contract: a completion event projects an already committed settlement. It identifies the turn and outcome; delegated-child completion also carries parent identity, so it does not stand in for the parent's completion. Clients can reconstruct the settlement metadata from durable state if the live notification is missed. This contract belongs to Sidekick's orchestration layer; a wrapped external harness's own stream events should not automatically receive the same meaning. [Completion projection][s-completion].

For example, a worker can emit text, fail, and be replaced while the same turn remains active. Monitoring should correlate the conversation, turn, worker attempt, and tool call separately. Record whether an observation means “streamed,” “committed,” or “settled”; a single “agent finished” timestamp would hide the recovery boundary. [Attempt replacement][s-attempt].

The codebase chapters identify concrete events and tests for each implementation. The [builder's lab](../build-a-harness.md) supplies deterministic scenarios for these boundaries. Together they provide a more useful starting point than a checklist of feature names.

[p-timing]: https://github.com/earendil-works/pi/blob/482c1381a00d8d00bc81697e4a980c593db6803e/packages/agent/src/agent-loop.ts#L820-L910
[p-code-timing]: https://github.com/earendil-works/pi/blob/482c1381a00d8d00bc81697e4a980c593db6803e/packages/coding-agent/src/extensions/codemode/execute.ts#L472-L502
[s-effects]: https://github.com/datex/sidekick/blob/463d653124e1c2cda46a3f14f01f3d6f384326b1/backend/src/sidekick/services/session_effect_executor.py#L41-L105
[s-dispatch]: https://github.com/datex/sidekick/blob/463d653124e1c2cda46a3f14f01f3d6f384326b1/backend/src/sidekick/services/session_dispatch.py#L92-L219
[s-completion]: https://github.com/datex/sidekick/blob/463d653124e1c2cda46a3f14f01f3d6f384326b1/backend/src/sidekick/services/turn_lifecycle.py#L67-L205
[s-attempt]: https://github.com/datex/sidekick/blob/463d653124e1c2cda46a3f14f01f3d6f384326b1/backend/src/sidekick/services/turn_record.py#L900-L1027
