fix: verdict death — plan→teach seam inferred from first nodeId-tagged quiz

The Accept/Decline verdict gate is gone (owner ruling 2026-09-26):
presenting the plan ends the teacher's turn; the learner's next message
is a natural reply. Teaching begins at the first quiz call tagged with a
nodeId (probe quizzes carry none) — both folds (view phaseAt3, native
phaseAt3Lh) advance on the call itself, and the teach divider renders
before that whole assistant block. No backwards compat: verdict markers,
the verdict input event, optimistic appends, composer buttons, and
projection all deleted; prompts and docs rewritten to the natural flow.
This commit is contained in:
amosblomqvist
2026-09-27 00:48:46 +03:00
parent dcb839232c
commit 145b470752
17 changed files with 221 additions and 389 deletions
+3 -18
View File
@@ -14,7 +14,7 @@
* sees it (verified single site, below).
*
* UI-ONLY CONTENT (owner ruling, fork 1 + the plan's custom-message
* taxonomy): verdict markers, the probe→teach handoff, sub-agent steers,
* taxonomy): the probe→teach handoff, sub-agent steers,
* and plan blocks are LhMarkerMessage — this app's declaration-merged
* member of pi-agent-core's CustomAgentMessages extension point, shaped
* exactly like pi's own CustomMessage ({role:"custom", customType,
@@ -36,7 +36,7 @@
import type { AgentMessage } from "@earendil-works/pi-agent-core";
import type { AssistantMessage, Message, ToolResultMessage, UserMessage } from "@earendil-works/pi-ai";
import { QUESTION_TOOLS } from "./pending.ts";
import { HANDOFF_TEXT, verdictText } from "./contracts/chat.ts";
import { HANDOFF_TEXT } from "./contracts/chat.ts";
/** The hard-invariant wording for an aborted turn's unanswered calls —
* carried over verbatim from the pre-native era so the model's view
@@ -58,7 +58,7 @@ export interface LhMarkerMessage {
/** Record identity (pi messages carry no id — see the file header). */
id: string;
role: "custom";
customType: "verdict" | "probe-handoff" | "subagent-steer" | "subagent-abort" | "plan-block";
customType: "probe-handoff" | "subagent-steer" | "subagent-abort" | "plan-block";
/** The model-facing text ("" for plan blocks — UI-only). */
content: string;
display: boolean;
@@ -125,21 +125,6 @@ export function newAnswerResult(
};
}
/** The plan verdict (the plan→teach seam): marker only — the model-facing
* wording is owned by verdictText (core/contracts/chat.ts), the UI
* renders the quiet accept/decline line off details. */
export function newVerdictMessage(accepted: boolean, at: string): LhMarkerMessage {
return {
id: newMessageId(),
role: "custom",
customType: "verdict",
content: verdictText(accepted),
display: true,
details: { accepted, at },
timestamp: Date.now(),
};
}
/** The probe→teach handoff wake: scaffolding, not speech — the model reads
* HANDOFF_TEXT, the UI renders the quiet system line. */
export function newHandoffMessage(chatId: string): LhMarkerMessage {