@@ -284,11 +284,34 @@ function buildLifecycleVisibleReplyUtils(ctx) {
284284 state . visible . workflowCompletion = projectWorkflowCompletionVisibleState ( completionProjection )
285285 }
286286 const evidence = getVisibleReplyEvidence ( payload )
287+ const visibleObservedAt = new Date ( ) . toISOString ( )
288+ state . visible . observedPromptCount = Number ( state . promptCount || 0 )
289+ state . visible . observedEventName = eventName
290+ state . visible . observedAt = visibleObservedAt
291+ state . visible . sampleFreshness = 'current'
292+ state . visible . staleReason = ''
287293 state . visible . replyEvidence = evidence . observed ? 'verified-present' : 'unverified'
288294 state . visible . replySource = evidence . source || ''
289295 state . visible . artifactEvidenceSource = evidence . source || ''
290296 if ( ! evidence . observed ) {
291297 // PF-163: unobserved payload cannot invent delivery; still surface semantic-artifact gap for completion evidence
298+ state . visible . payloadObserved = false
299+ state . visible . precheck = false
300+ state . visible . precheckStatus = 'unverified'
301+ state . visible . precheckMissingItems = [ ]
302+ state . visible . entryCheckCompleteness = {
303+ claimed : false ,
304+ complete : false ,
305+ status : 'not-claimed' ,
306+ missingPcs : [ ] ,
307+ missingItems : [ ] ,
308+ foldedRanges : [ ] ,
309+ presentPcs : [ ] ,
310+ sourceSchemaVersion : null ,
311+ migrationStatus : 'not-claimed'
312+ }
313+ state . visible . sampleFreshness = 'unverified'
314+ state . visible . staleReason = 'visible-payload-unobserved'
292315 state . visible . artifactStatus = 'unverified'
293316 state . visible . artifactMissingItems = [ 'visible-payload-unobserved' , 'semantic-artifact-items' ]
294317 state . visible . finalValidationSummaryStatus = 'unverified'
@@ -436,7 +459,29 @@ function buildLifecycleVisibleReplyUtils(ctx) {
436459 if ( eventName === 'Stop' ) fs . unlinkSync ( statePaths . finalPayloadFlag )
437460 }
438461
462+ function getVisibleReplyFreshness ( state ) {
463+ const visible = state ?. visible
464+ if ( ! visible || visible . payloadObserved !== true ) return { status : 'unverified' , reason : 'no-visible-payload' }
465+ const currentPromptCount = Number ( state . promptCount || 0 )
466+ const observedPromptCount = Number ( visible . observedPromptCount || 0 )
467+ if ( ! observedPromptCount || observedPromptCount !== currentPromptCount ) {
468+ visible . sampleFreshness = 'stale'
469+ visible . staleReason = 'prompt-count-mismatch'
470+ return {
471+ status : 'stale' ,
472+ reason : 'prompt-count-mismatch' ,
473+ observedPromptCount,
474+ currentPromptCount
475+ }
476+ }
477+ visible . sampleFreshness = 'current'
478+ visible . staleReason = ''
479+ return { status : 'current' , reason : '' }
480+ }
481+
439482 function getPrecheckEvidenceStatus ( state ) {
483+ const freshness = getVisibleReplyFreshness ( state )
484+ if ( freshness . status === 'stale' ) return 'unverified'
440485 if ( state . visible ?. precheck ) return 'verified-present'
441486 if ( state . visible ?. precheckStatus === 'verified-missing' ) return 'verified-missing'
442487 if ( state . visible ?. payloadObserved ) return 'verified-missing'
@@ -488,7 +533,11 @@ function buildLifecycleVisibleReplyUtils(ctx) {
488533 items . push ( 'entry check block 未输出(S07/C18:首条用户可见回复必须含 PC0~PC10 入口检查块)' )
489534 }
490535 } else if ( eventName === 'Stop' && precheckStatus === 'unverified' ) {
491- items . push ( `无法验证最终用户可见回复是否包含入口检查块(Stop/PreCompact 未提供可解析 assistant 内容;如需取证请创建 ${ getStatePaths ( state ) . finalPayloadFlag } 后重试)` )
536+ const freshness = getVisibleReplyFreshness ( state )
537+ const reason = freshness . status === 'stale'
538+ ? `可见回复样本已过期(${ freshness . reason } ,observedPromptCount=${ freshness . observedPromptCount || 0 } , currentPromptCount=${ freshness . currentPromptCount || 0 } )`
539+ : `Stop/PreCompact 未提供可解析 assistant 内容;如需取证请创建 ${ getStatePaths ( state ) . finalPayloadFlag } 后重试`
540+ items . push ( `无法验证最终用户可见回复是否包含入口检查块(${ reason } )` )
492541 }
493542 settleS07OrderStatus ( state , eventName )
494543 if ( eventName === 'Stop' && state . visible ?. s07OrderStatus === 'late' ) {
@@ -573,6 +622,7 @@ function buildLifecycleVisibleReplyUtils(ctx) {
573622 analyzeEntryCheckCompleteness,
574623 updateVisibleReplyState,
575624 captureFinalPayloadSample,
625+ getVisibleReplyFreshness,
576626 getPrecheckEvidenceStatus,
577627 settleS07OrderStatus,
578628 buildClosureReminder,
0 commit comments