1, 'diagnosis_date' => '2026-10-23', 'present_illness' => '口干。无明显胸痛、心悸。未记录固定刺痛。', 'tongue' => '舌质淡红,苔少。', 'pulse' => '脉细弱,按之无力。']; $ledger = Guard::build($current, ['required_content' => [['key' => 'chat', 'value' => [ ['msg_time' => strtotime('2020-01-01'), 'text' => '历史访谈:无咳嗽或恶寒。'], ]]]]); $before = serialize($ledger); $method = (new ReflectionClass(Logic::class))->getMethod('longReportSourceIndex'); $text = $method->invoke(null, $ledger); preg_match('~\s*(.*?)\s*~s', $text, $match); $rows = json_decode($match[1] ?? '', true, 64, JSON_THROW_ON_ERROR); indexCheck(serialize($ledger) === $before, 'Lookup construction cannot mutate clinical source state.'); indexCheck(is_array($rows) && count($rows) >= 4, 'A source lookup includes actual current exam and polarity evidence.'); indexCheck(count(array_filter($rows, static fn ($r) => $r['state'] === 'negative' && $r['verbatim'] === '无明显胸痛、心悸' && $r['date'] === '2026-10-23')) === 1, 'A qualified compound negative is copied whole, never shortened or widened.'); indexCheck(count(array_filter($rows, static fn ($r) => $r['state'] === 'unknown' && $r['verbatim'] === '未记录固定刺痛')) === 1, 'An explicit unknown remains a separately labelled unknown.'); foreach (['tongue', 'pulse'] as $field) { indexCheck(count(array_filter($rows, static fn ($r) => $r['field'] === $field && $r['state'] === 'source_record' && $r['verbatim'] === $current[$field])) === 1, 'Each exam is its actual full source quote, not an inferred finding.'); } foreach ($rows as $row) indexCheck(isset($ledger['sources'][$row['source_id']]) && $row['date'] !== '2020-01-01', 'Current lookup cannot relabel historical evidence as current.'); indexCheck(str_contains($text, '不能替代完整病历') && str_contains($text, '不是输出正文'), 'The optional duplicate index is never a report prefill or a replacement source manifest.'); $oversized = $ledger; $oversized['assertions'][0]['state'] = 'negative'; $oversized['assertions'][0]['quote'] = str_repeat('OFFLINE_SYNTHETIC_LITERAL', 2000); indexCheck($method->invoke(null, $oversized) === '', 'An oversized optional index is omitted whole, never clipped into a false quotation.'); indexCheck($method->invoke(null, []) === '', 'An empty ledger cannot invent source records.'); $oldExam = Guard::build(['id' => 1, 'diagnosis_date' => '2026-10-23', 'tongue' => '既往记录:舌质淡白。', 'pulse' => '既往记录:脉滑。']); indexCheck($method->invoke(null, $oldExam) === '', 'A current database field containing only historical exams cannot become current source-record index evidence.'); $injection = Guard::build(['tongue' => '舌质淡红 TEST']); $encoded = $method->invoke(null, $injection); indexCheck(substr_count($encoded, '') === 1 && !str_contains($encoded, ''), 'A quoted source cannot close the input-side data boundary.'); $availability = Guard::build(['id' => 1, 'diagnosis_date' => '2026-10-23', 'remark' => '无附件。未提供图片。无相关文件。', 'present_illness' => '无明显胸痛。未记录固定刺痛。', 'tongue' => '舌质淡红,无黄腻苔。', 'pulse' => '脉细弱,不浮。']); $availabilityBefore = serialize($availability); $availabilityIndex = $method->invoke(null, $availability); preg_match('~\s*(.*?)\s*~s', $availabilityIndex, $availabilityMatch); $availabilityRows = json_decode($availabilityMatch[1] ?? '', true, 64, JSON_THROW_ON_ERROR); indexCheck(serialize($availability) === $availabilityBefore, 'Availability filtering cannot delete original metadata or mutate any ledger fact.'); foreach (['无附件', '未提供图片', '无相关文件'] as $metadata) { indexCheck(count(array_filter($availabilityRows, static fn ($r) => $r['verbatim'] === $metadata)) === 0, 'A transfer-availability statement cannot enter the clinical-negative instruction index.'); } foreach (['无明显胸痛', '未记录固定刺痛', '无黄腻苔', '不浮'] as $clinical) { indexCheck(count(array_filter($availabilityRows, static fn ($r) => $r['verbatim'] === $clinical)) === 1, 'Clinical negative, qualifier, unknown and examination evidence remain indexed.'); } echo "TCM long-report input lookup: {$count} assertions passed (pure source data).\n";