@@ -173,8 +173,73 @@ function classifyDocsAudienceDisambiguationSample(disambiguationText) {
173173 return 'ok'
174174}
175175
176+ /**
177+ * Cognitive altitude for public-user guide/readme bodies.
178+ * Detects "complete but unreadable" function-inventory quick starts.
179+ *
180+ * @param {string } body markdown or free text
181+ * @param {{ surface?: string } } [opts]
182+ * @returns {'ok'|'function-inventory-as-guide'|'concept-dump-no-task'|'ok-reference-dense'|'not-applicable' }
183+ */
184+ function classifyUserDocsCognitiveAltitudeSample ( body , opts = { } ) {
185+ const text = String ( body || '' )
186+ if ( ! text . trim ( ) ) return 'not-applicable'
187+
188+ const surface = String ( opts . surface || 'guide' ) . toLowerCase ( )
189+ const head = text . slice ( 0 , 1200 )
190+
191+ // Identifier-call chains: foo( bar( or a.b.c( density
192+ const callLike = ( head . match ( / \b [ A - Z a - z _ ] [ \w . ] * \s * \( / g) || [ ] ) . length
193+ const taskLanguage = / 你 要 | 完 成 | 目 标 是 | 场 景 | 例 如 你 | 第 一 次 | 安 装 后 | 发 一 条 | 创 建 一 个 | 如 何 | 怎 么 | 步 骤 \s * [ 1 1 一 ] | 推 荐 路 径 | 适 合 谁 / i. test ( head )
194+ const conceptOnly = / 架 构 | 生 命 周 期 | 模 型 | 组 件 | 模 块 | 设 计 | 原 理 / i. test ( head ) && ! taskLanguage && callLike < 2
195+
196+ if ( surface === 'reference' ) {
197+ // Reference may be symbol-dense; still flag pure call lists with zero purpose lines if extreme
198+ if ( callLike >= 8 && ! / 用 途 | 何 时 | 用 于 | u s e w h e n | p u r p o s e / i. test ( text ) && ! taskLanguage ) {
199+ return 'function-inventory-as-guide'
200+ }
201+ return 'ok-reference-dense'
202+ }
203+
204+ // guide / readme / quick start
205+ if ( callLike >= 3 && ! taskLanguage ) return 'function-inventory-as-guide'
206+ // quick-start section that is only chained calls
207+ if ( / 快 速 开 始 | q u i c k \s * s t a r t | g e t t i n g s t a r t e d / i. test ( head ) ) {
208+ const qs = head . split ( / 快 速 开 始 | q u i c k \s * s t a r t | g e t t i n g s t a r t e d / i) [ 1 ] || ''
209+ const qsCalls = ( qs . slice ( 0 , 500 ) . match ( / \b [ A - Z a - z _ ] [ \w . ] * \s * \( / g) || [ ] ) . length
210+ if ( qsCalls >= 3 && ! / 安 装 | i n s t a l l | n p m | p n p m | y a r n / i. test ( qs . slice ( 0 , 500 ) ) ) {
211+ return 'function-inventory-as-guide'
212+ }
213+ }
214+ if ( conceptOnly && head . length > 200 ) return 'concept-dump-no-task'
215+ return 'ok'
216+ }
217+
218+ /**
219+ * Whether an assistant reply proactively extended scenarios after a user pain point.
220+ * @param {string } userMessage
221+ * @param {string } assistantReply
222+ * @returns {'ok'|'missing-extension'|'not-applicable' }
223+ */
224+ function classifyProactiveScenarioExtensionSample ( userMessage , assistantReply ) {
225+ const u = String ( userMessage || '' )
226+ const a = String ( assistantReply || '' )
227+ if ( ! u . trim ( ) || ! a . trim ( ) ) return 'not-applicable'
228+ // User raised a concrete docs/process issue
229+ const isPain = / 问 题 | 看 不 懂 | 复 杂 | 场 景 | 还 有 | 为 什 么 | 如 何 处 理 | 痛 点 | 失 败 / i. test ( u )
230+ if ( ! isPain ) return 'not-applicable'
231+ // Assistant lists multiple related scenarios (tables, A1/B1, 场景)
232+ const extendsScenes = ( / 场 景 / . test ( a ) && ( a . match ( / 场 景 / g) || [ ] ) . length >= 2 ) ||
233+ / \| .* 场 景 .* \| / . test ( a ) ||
234+ / A \d | B \d | C \d | 同 类 | 延 展 | 还 有 .* 情 况 | 相 关 失 败 / i. test ( a )
235+ if ( ! extendsScenes ) return 'missing-extension'
236+ return 'ok'
237+ }
238+
176239module . exports = {
177240 classifyDocsAudienceSample,
178241 classifyDocsAudienceDriftSample,
179- classifyDocsAudienceDisambiguationSample
242+ classifyDocsAudienceDisambiguationSample,
243+ classifyUserDocsCognitiveAltitudeSample,
244+ classifyProactiveScenarioExtensionSample
180245}
0 commit comments