quiz nodeId required (owner ruling 2026-09-26): no untagged teach quizzes — boundary rejects, model retries tagged; off-map checks route to ask_user_question; anti-rush doctrine in schema+prompt; docs+comments updated
This commit is contained in:
@@ -55,9 +55,9 @@ export type PlanNodeStatus = "current" | "visited" | "upcoming";
|
||||
// node is the teacher's judgment the previous one is finished, regardless of
|
||||
// check outcomes (a failed check then a move-on is still visited); results
|
||||
// feed nothing; there is NO fallback current (before the first tagged check
|
||||
// nothing is current). Untagged checks are legal ad-hoc checks — they move
|
||||
// nothing. NodeIds missing from the current tree are ignored (a rewrite
|
||||
// may have dropped the node).
|
||||
// nothing is current). Untagged checks no longer exist (nodeId is required
|
||||
// on the teach quiz, owner ruling 2026-09-26). NodeIds missing from the
|
||||
// current tree are ignored (a rewrite may have dropped the node).
|
||||
|
||||
/** Minimal structural message slice — anything with typed parts (mirrors
|
||||
* phases.ts: pure, no runtime deps, safe on server, client, and in tests). */
|
||||
|
||||
+3
-2
@@ -17,8 +17,9 @@
|
||||
* turn, and the learner's next message is a natural reply (a change
|
||||
* request, or the go-ahead). The live indicator LAGS by design (owner
|
||||
* accepted): "teach" shows only once the first node's question is posed.
|
||||
* A teacher that never tags a quiz would sit in "plan" visually —
|
||||
* off-doctrine (tagging is prompt-mandated and nodeId is call-validated).
|
||||
* A teacher that never tags a quiz can no longer exist — nodeId is
|
||||
* schema-required at the teach quiz boundary (owner ruling 2026-09-26),
|
||||
* so the seam signal is structural, not prompt-mandated.
|
||||
*
|
||||
* The former derived-occupancy seam (phase-of-tree via `currentNodeId`)
|
||||
* is GONE, as is the verdict-marker fold: no backwards compatibility
|
||||
|
||||
@@ -200,16 +200,15 @@ export const quizInputBase = Type.Object({
|
||||
// never touches).
|
||||
export const quizInputObject = Type.Object({
|
||||
...quizInputBase.properties,
|
||||
nodeId: Type.Optional(
|
||||
Type.String({
|
||||
description:
|
||||
"Optional plan-tree node id this question is about — must EXACTLY match one of this session's " +
|
||||
"plan_init node slugs (validated at call time; a mismatched id is rejected back to you). " +
|
||||
"Tag every question that targets a map node: the lesson's position on the map derives from these tags " +
|
||||
"(the node the latest tagged question is about is where the map stands; earlier ones count as visited). " +
|
||||
"Omit for quick ad-hoc checks that don't target a node.",
|
||||
}),
|
||||
),
|
||||
nodeId: Type.String({
|
||||
description:
|
||||
"REQUIRED plan-tree node id this question is about — must EXACTLY match one of this session's " +
|
||||
"plan_init node slugs (validated at call time; a mismatched id is rejected back to you). " +
|
||||
"The lesson's position on the map derives from these tags (the node the latest tagged question is about is " +
|
||||
"where the map stands; earlier ones count as visited). A node takes as many questions as it deserves: stay on " +
|
||||
"one node for as many turns as the understanding needs — one reasoning step at a time, never rush forward. " +
|
||||
"For off-map checks use ask_user_question.",
|
||||
}),
|
||||
});
|
||||
|
||||
/** The PROBE-side quiz declaration: the shared authoring contract, no
|
||||
|
||||
Reference in New Issue
Block a user