@@ -7,6 +7,12 @@ import type {
77 EvidenceClass ,
88} from "./types.js" ;
99import { isConceptualProbe } from "./conceptualProbe.js" ;
10+ import {
11+ assessConversationContinue ,
12+ } from "./conversationContinue.js" ;
13+ import {
14+ assessStructuredCritique ,
15+ } from "./structuredCritique.js" ;
1016import { normalizeCanonicalInputText } from "./inputNormalization.js" ;
1117
1218const GREETING_PATTERNS = [
@@ -125,23 +131,77 @@ function classifyIntentText(text: string, event: CanonicalEvent): IntentClass {
125131 return "irrelevant" ;
126132}
127133
128- function classifyIntent ( event : CanonicalEvent ) : IntentClass {
134+ function classifyIntentTrace ( event : CanonicalEvent ) : {
135+ intent : IntentClass ;
136+ baseIntent : IntentClass ;
137+ hasParentContext : boolean ;
138+ continuationSignal : boolean ;
139+ continuationSupportScore : number ;
140+ structuredCritiqueSignal : boolean ;
141+ structuredCritiqueSupportScore : number ;
142+ } {
129143 const normalization = normalizeCanonicalInputText ( event . text ) ;
130144 for ( const candidate of normalization . classifierTextCandidates ) {
131145 const intent = classifyIntentText ( candidate , event ) ;
146+ const continuation = assessConversationContinue ( candidate , event ) ;
147+ const critique = assessStructuredCritique ( candidate , event ) ;
148+
149+ if ( ( intent === "question" || intent === "irrelevant" ) && continuation . continuationSignal ) {
150+ return {
151+ intent : "conversation_continue" ,
152+ baseIntent : intent ,
153+ hasParentContext : continuation . hasParentContext ,
154+ continuationSignal : true ,
155+ continuationSupportScore : continuation . continuationSupportScore ,
156+ structuredCritiqueSignal : false ,
157+ structuredCritiqueSupportScore : critique . structuredCritiqueSupportScore ,
158+ } ;
159+ }
160+
161+ if ( ( intent === "question" || intent === "irrelevant" ) && critique . structuredCritiqueSignal ) {
162+ return {
163+ intent : "structured_critique" ,
164+ baseIntent : intent ,
165+ hasParentContext : critique . hasParentContext ,
166+ continuationSignal : false ,
167+ continuationSupportScore : continuation . continuationSupportScore ,
168+ structuredCritiqueSignal : true ,
169+ structuredCritiqueSupportScore : critique . structuredCritiqueSupportScore ,
170+ } ;
171+ }
172+
132173 if ( intent !== "irrelevant" ) {
133- return intent ;
174+ return {
175+ intent,
176+ baseIntent : intent ,
177+ hasParentContext : continuation . hasParentContext ,
178+ continuationSignal : false ,
179+ continuationSupportScore : continuation . continuationSupportScore ,
180+ structuredCritiqueSignal : false ,
181+ structuredCritiqueSupportScore : critique . structuredCritiqueSupportScore ,
182+ } ;
134183 }
135184 }
136185
137- return "irrelevant" ;
186+ const continuation = assessConversationContinue ( normalization . normalizedText , event ) ;
187+ const critique = assessStructuredCritique ( normalization . normalizedText , event ) ;
188+ return {
189+ intent : "irrelevant" ,
190+ baseIntent : "irrelevant" ,
191+ hasParentContext : continuation . hasParentContext ,
192+ continuationSignal : false ,
193+ continuationSupportScore : continuation . continuationSupportScore ,
194+ structuredCritiqueSignal : false ,
195+ structuredCritiqueSupportScore : critique . structuredCritiqueSupportScore ,
196+ } ;
138197}
139198
140199function classifyTarget ( event : CanonicalEvent , intent : IntentClass ) : TargetClass {
141200 if ( event . cashtags . length > 0 ) return "token" ;
142201 if ( intent === "embodiment_query" ) return "embodiment" ;
143202 if ( intent === "lore_query" ) return "lore" ;
144203 if ( intent === "conceptual_probe" ) return "claim" ;
204+ if ( intent === "structured_critique" ) return "claim" ;
145205 if ( intent === "greeting" || intent === "casual_ping" || intent === "conversation_continue" ) return "conversation" ;
146206 if ( intent === "market_question_general" ) return "market_structure" ;
147207 if ( intent === "accusation" ) return "behavior" ;
@@ -154,8 +214,8 @@ function classifyTarget(event: CanonicalEvent, intent: IntentClass): TargetClass
154214
155215function classifyEvidence ( event : CanonicalEvent , intent : IntentClass ) : EvidenceClass {
156216 const text = event . text ;
157- const hasParent = ! ! event . parent_text ;
158- const hasContext = event . conversation_context . length > 0 ;
217+ const hasParent = ! ! event . parent_text ?. trim ( ) ;
218+ const hasContext = event . conversation_context . length > 0 || Boolean ( event . context ?. trim ( ) ) || Boolean ( event . quoted_text ?. trim ( ) ) ;
159219
160220 const productProof = countPatternMatches ( text , PRODUCT_PROOF_PATTERNS ) ;
161221 const parentProof = event . parent_text
@@ -165,7 +225,7 @@ function classifyEvidence(event: CanonicalEvent, intent: IntentClass): EvidenceC
165225 if ( productProof >= 2 || ( productProof >= 1 && parentProof >= 1 ) ) {
166226 return "self_contained_strong" ;
167227 }
168- if ( intent === "conceptual_probe" ) {
228+ if ( intent === "conceptual_probe" || intent === "structured_critique" ) {
169229 return "contextual_medium" ;
170230 }
171231 if ( hasParent || hasContext || productProof >= 1 ) {
@@ -210,10 +270,18 @@ function extractEvidenceBullets(event: CanonicalEvent, intent: IntentClass): str
210270 if ( intent === "conceptual_probe" ) {
211271 bullets . push ( "structured frontier question" ) ;
212272 }
273+ if ( intent === "structured_critique" ) {
274+ bullets . push ( "structured skepticism about incentives or architecture" ) ;
275+ }
213276 if ( countPatternMatches ( text , PERFORMANCE_PATTERNS ) > 0 ) {
214277 bullets . push ( "includes unverified performance claims" ) ;
215278 }
216- if ( countPatternMatches ( text , PRODUCT_PROOF_PATTERNS ) === 0 && intent !== "question" ) {
279+ if (
280+ countPatternMatches ( text , PRODUCT_PROOF_PATTERNS ) === 0 &&
281+ intent !== "question" &&
282+ intent !== "conversation_continue" &&
283+ intent !== "structured_critique"
284+ ) {
217285 bullets . push ( "no concrete product proof in visible text" ) ;
218286 }
219287 if ( countPatternMatches ( text , VOLUME_BEHAVIOR_PATTERNS ) > 0 ) {
@@ -273,7 +341,8 @@ function classifyPolicyBlock(intent: IntentClass, spamProb: number, riskFlags: s
273341}
274342
275343export function classify ( event : CanonicalEvent ) : ClassifierOutput {
276- const intent = classifyIntent ( event ) ;
344+ const intentTrace = classifyIntentTrace ( event ) ;
345+ const intent = intentTrace . intent ;
277346 const target = classifyTarget ( event , intent ) ;
278347 const evidence_class = classifyEvidence ( event , intent ) ;
279348 const bait_probability = estimateBaitProbability ( event ) ;
@@ -293,5 +362,11 @@ export function classify(event: CanonicalEvent): ClassifierOutput {
293362 policy_reasons : policy . reasons ,
294363 evidence_bullets,
295364 risk_flags,
365+ baseIntent : intentTrace . baseIntent ,
366+ hasParentContext : intentTrace . hasParentContext ,
367+ continuationSignal : intentTrace . continuationSignal ,
368+ continuationSupportScore : intentTrace . continuationSupportScore ,
369+ structuredCritiqueSignal : intentTrace . structuredCritiqueSignal ,
370+ structuredCritiqueSupportScore : intentTrace . structuredCritiqueSupportScore ,
296371 } ;
297372}
0 commit comments