Only a literal pattern may take the personal boundary off a turn (V-666)
Naming a destination takes the guessing query sources off a turn, and the personal boundary is one of them. Every other guesser costs an answer when it is wrongly dropped. This one costs the rule that a question about him never reaches an upstream engine. Three deciders name a destination now and two of them infer it: the routing heads and the resident model. Decision.SourceAnchored says a stage 0 grammar read the words instead. queryWalk honours it for the source marked boundary: true and for no other, so the rest of the table is unchanged. Owner's call of 2026-08-09. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013ptwopxyo3Z2kwFckHkLvN
This commit is contained in:
@@ -111,6 +111,21 @@ type Decision struct {
|
||||
// before this field existed. See source.go for why it is twelve values.
|
||||
Source Source
|
||||
|
||||
// SourceAnchored — a stage 0 grammar named that destination, matching a
|
||||
// literal pattern to do it. Only the router sets this, and only there.
|
||||
//
|
||||
// It exists because one thing downstream is not reversible by evidence
|
||||
// (V-666). Naming a destination normally takes guessing sources off a turn,
|
||||
// and one of those is the personal boundary, which is what stops a question
|
||||
// about him from reaching the world. A grammar that read "что такое X" may
|
||||
// take it off. A model or a softmax may not, because a wrong destination
|
||||
// there widens what leaves the box rather than costing an answer.
|
||||
//
|
||||
// Read Stage instead and the two decisions get coupled: stage 0 also means
|
||||
// confidence 1.0 and an anchored claim band, and a later cascade change
|
||||
// could make one true where the other is not.
|
||||
SourceAnchored bool
|
||||
|
||||
// Continued — this decision was rebuilt from the previous turn rather
|
||||
// than routed, because the utterance was an ellipsis ("а завтра?").
|
||||
// Handlers use it to know that Slots.Text is the PREVIOUS turn's topic
|
||||
|
||||
@@ -98,6 +98,10 @@ func (r *Router) Route(ctx context.Context, utterance string, now time.Time) (De
|
||||
continue // grammar matched shape but not content → fall through
|
||||
}
|
||||
d.Utterance = utterance
|
||||
// A literal pattern named that destination, which is the one provenance
|
||||
// allowed to take the personal boundary off a turn (V-666). Set here and
|
||||
// nowhere else, so no other arm of the cascade can claim it.
|
||||
d.SourceAnchored = d.Source != SourceUnknown
|
||||
// The grammar decided the intent; the extractor fills the slots it did
|
||||
// not match (V-572). See fillMatchedSlots for why every grammar gets it.
|
||||
r.fillMatchedSlots(ctx, &d, now)
|
||||
|
||||
Reference in New Issue
Block a user