0a2e194e76
Migrate the two remaining action-routing consumers from compatibility Decision.Slings fields to authoritative Decision.CapabilitySelection: - refusesCommand: reads CapabilitySelection.Fn instead of Slots.Fn - ActHasEntityTarget: reads CapabilitySelection.Resolved and CapabilitySelection.Args instead of Slots.HasFn and Slots.Args Slots.Text remains the source for entity text when positional args do not contain the target (unchanged). Regression tests prove: - prohibited sentinel preserved byte-for-byte through SelectCapability - blanked Slots.Fn/Args/HasFn do not affect migrated consumers - Praxis/Hexis entity-target routing unchanged - stage-0 deterministic act unchanged - classifier/extractor act unchanged do not remove the compatibility mirrors yet.
44 lines
1.5 KiB
Go
44 lines
1.5 KiB
Go
package router
|
|
|
|
import "github.com/kami/maven/internal/lexicon"
|
|
|
|
// ActHasEntityTarget reports whether an act names something that Nexus may be
|
|
// asked to resolve. A local zero-argument tool may still be valid; this gate is
|
|
// only about crossing into the ecosystem, where an entity is mandatory.
|
|
//
|
|
// A matched function carries its target in Args. An unmatched entity act is
|
|
// the Hexis discovery lane, so it must at least contain a verb plus a subject.
|
|
// A bare verb and a demonstrative-only tail carry no target evidence and stay
|
|
// local/clarify instead of sending free ambiguity to Nexus.
|
|
func ActHasEntityTarget(decision Decision) bool {
|
|
if decision.Intent != IntentAct {
|
|
return false
|
|
}
|
|
if decision.CapabilitySelection.Resolved {
|
|
if len(decision.CapabilitySelection.Args) > 0 {
|
|
return hasNamedEntityToken(decision.CapabilitySelection.Args)
|
|
}
|
|
// A resident-model act may name the accepted verb and its target in
|
|
// Text while leaving Args empty. Resolved establishes that the first token
|
|
// is the operation; only a meaningful tail can establish the entity.
|
|
tokens := planTokens(decision.Slots.Text)
|
|
return len(tokens) > 1 && hasNamedEntityToken(tokens[1:])
|
|
}
|
|
tokens := planTokens(decision.Slots.Text)
|
|
if len(tokens) < 2 {
|
|
return false
|
|
}
|
|
return hasNamedEntityToken(tokens[1:])
|
|
}
|
|
|
|
func hasNamedEntityToken(tokens []string) bool {
|
|
references := lexicon.UnresolvedReferences()
|
|
for _, token := range tokens {
|
|
if lexicon.IsFillerParticle(token) || hasExactWord(references, token) {
|
|
continue
|
|
}
|
|
return true
|
|
}
|
|
return false
|
|
}
|