'synthetic', 'text' => $text, 'start_ms' => 0, 'end_ms' => 10000]]; $catalog = ['diagnosis' => [['key' => 'current_medications', 'label' => '在用药物', 'type' => 'text', 'max' => 2000, 'semantic' => '当前用药状态;不是某日执行', 'recording_rules' => ['规范化,不扩张否定范围']]]]; $prompt = Prompt::build($text, $segments, '2026-01-01 10:00:00', $catalog); $check('shared_rules_once', substr_count($prompt, $rules) === 1); $check('context_keeps_field_contract', str_contains($prompt, '"max":2000') && str_contains($prompt, '"semantic":')); $check('verbatim_source_unchanged', Prompt::citations($segments)[0]['text'] === $text); $check('canonical_source_once', substr_count($prompt, $text) === 1); foreach (['openai', 'dify_chat'] as $protocol) { $provider = ['fingerprint' => str_repeat('b', 64), 'extraction' => ['protocol' => $protocol, 'model' => 'synthetic', 'response_format' => 'prompt_json', 'binding_revision' => 'synthetic-v1']]; $request = (new Pipeline([], $provider))->extractRequest($text, $segments, '2026-01-01 10:00:00', $catalog); $check('real_request:' . $protocol, ($request['query'] ?? $request['messages'][0]['content']) === $prompt); } // Real legacy prompt method with an isolated dictionary, not production initialization. new think\App(); $manager = new think\DbManager(); $manager->setConfig(['default' => 'sqlite', 'connections' => ['sqlite' => ['type' => 'sqlite', 'database' => ':memory:', 'prefix' => 'zyt_']]]); think\Container::getInstance()->instance('think\DbManager', $manager); think\facade\Db::execute('CREATE TABLE zyt_dict_data (id INTEGER PRIMARY KEY, type_value TEXT, status INTEGER, sort INTEGER, name TEXT, value TEXT)'); $method = new ReflectionMethod(Dify::class, 'prompt'); $method->setAccessible(true); $instance = (new ReflectionClass(Dify::class))->newInstanceWithoutConstructor(); $legacy = $method->invoke($instance, '2026-01-01 10:00:00', 10.0); $check('legacy_audio_shared_rules_once', substr_count($legacy, $rules) === 1); $check('legacy_schema_still_v1', str_contains($legacy, 'followup-audio-v1')); $check('schema_still_v2', str_contains($prompt, 'followup-audio-transcript-v2')); } $failed = array_keys(array_filter($checks, static fn (bool $ok): bool => !$ok)); echo 'FOLLOWUP_AUDIO_RECORDING_RULES passed=' . (count($checks) - count($failed)) . '/' . count($checks) . ' failures=' . json_encode($failed, JSON_UNESCAPED_UNICODE) . ' clinical_writes=0 model_calls=0' . PHP_EOL; exit($failed === [] ? 0 : 1);