Add SystemMessage.replace: replaying a system message with the flag discards the
accumulated prompt content, sections, and tools before applying it, and providers
collapse the transcript into one leading system message whenever a later message
replaces it.
A forced prompt from before_agent_start is opaque, so it is persisted as a replace
message holding the text in content with no sections (the agent loop fills in the
full tool set). Leaving force mode persists another replace message with the
structured sections. Previously the forced prompt became a preamble section patch,
so models with native mid-conversation system messages kept the original prompt
as their leading system prompt and received the forced one as a later update.
* fix(coding-agent): fail closed on user bash hook errors
Prevent failed execution-routing hooks from falling back to the local shell.
Fixes#9068
* fix(coding-agent): validate user bash hook results
* docs(coding-agent): clarify user bash result semantics
* docs(coding-agent): streamline user bash semantics
* fix(coding-agent): strengthen user bash regressions
* docs(coding-agent): clarify user bash breaking change
Extract Google catalog processing and apply models.dev reasoning effort
metadata directly for Google, Vertex, and OpenCode models. Keep the
provider-specific Gemma 4 toggle mapping.
This change makes system prompt text and tool changes part of the transcript rather than silently rewriting its starting conditions. This lets Pi record when instructions changed or tools became available, restore that state after resuming or navigating branches, and preserve cached prompt prefixes where the upstream supports it.
- Envelope carries a contiguous per-watch revision; storage Seq stays internal;
Chord bridge publishes off the line through a bounded ordered adapter
- Namespaces reach the view only through a declared view projection; memos and
slot working state are never in the view
- memoOnce uses property presence; memos are coordination/evidence, not
exactly-once; idempotency key before the effect
- Hooks bound to their namespace token; BeforeToolApi.waiting(ctx) is async;
memo keys are (task, namespace, name)
- Reload: quiescent hold/reload/release, otherwise suspend/reopen; no handler
withdrawal machinery in v1; Namespace.unregister
- pi.* entry names reject except pi.notice; config reset is an operation;
generation failures run the final boundary and start successors