6cc177a76c
Move the six surface-switch helpers out of the conversation_loop facade into agent/surface_switch.py (AGENTS.md: new behaviour goes in a topical sibling), and fold the review findings on #104494: - MoA and codex_app_server turns never stamp the api_content sidecar, so the staged note could not be read back from the transcript and was re-sent on every turn after a switch. Those modes now skip the note (stored prompt still reused). - The announced surface was parsed with split(".") — a plugin platform with a dot in its name would never compare equal and re-stage the note every turn. The note now closes the name with a fixed terminator. - One identity-line parser (identity_line_value) shared by _stored_prompt_matches_runtime and the switch detector instead of two copies of the runtime-boundary/rpartition logic; tool names via the existing tools.mcp_tool_agent._def_name; the transcript scan is bounded to the last 200 rows (it ran every turn over the whole history). - consume_surface_switch_note reduced to a plain pop; developer-guide prompt-assembly.md updated (Platform is no longer an identity field); 17 new tests trimmed to 10 (same-shape pin/retire variants folded). Restoring Platform as an identity field still turns 5 tests red.