Skip to main content
Glama
norton77930

Podcast Ingestion Core MCP Server

by norton77930

Podcast Ingestion Core

Spec034 Task #77 current terminal is startup/plugin closed; credential_provider BLOCKED; overall BLOCKED. Its H2-frozen exact 20-file official NousResearch/hermes-agent bundle is static/offline only: startup order and the fixed security-guidance plugin identity chain are closed, while credential/provider construction data flow, whole-program closure, dynamic/user/project/entry-point plugin paths, runtime/secret edges, and actual activation remain blocked or unobserved. runtime_status=not_run; live_actions_authorized=false. The fresh review-only bootstrap/final trust chain is reserved for Main after both reviews PASS and remains unrun.

Podcast Ingestion Core — это универсальное ядро для приёма подкастов. В настоящее время реализованы: список эпизодов RSS, поиск эпизода, загрузка аудио, локальное транскрибирование faster-whisper, проверка транскриптов, детерминированное экстрактивное реферирование в Markdown, конвейер семантического реферирования через LLM, совместимый с OpenAI, детерминированное извлечение упоминаний, кэш/поиск метаданных SQLite, а также локальный stdio и loopback Streamable HTTP sidecar, использующие общий экземпляр FastMCP. Прямая интеграция Hermes MCP/config/Skills работает; проверка равенства конечных точек контента/метаданных C6 до/после из Spec 026 подтверждена обязательными рецензентами и единственным живым прогоном v2 как PASS-current, при этом не утверждается отсутствие транзиентных мутаций между снимками. C7 по-прежнему не имеет безопасных сред выполнения; тег v0.20.0 v2026.8.3 hooks — лишь кандидат, общий статус остаётся Blocked. Веб-интерфейс, планировщик, эмбеддинги и векторный поиск ещё не реализованы.

Первый профиль подкаста — Gooaye 股癌, но ядро не должно быть жёстко привязано к 股癌. Все настройки, специфичные для подкаста, хранятся в config/podcasts.yaml.

Передача ИИ-агенту / С чего начать

Этот README — краткая ориентация (структура каталогов, примеры CLI, история фаз), а не полный источник правил. Новому ИИ-агенту или разработчику следует начать отсюда:

  • Точка входа для передачи (10 минут на понимание репозитория): docs/agent-handoff.md

  • Структура разработки ИИ (иерархия инструкций, классификация изменений, DoR/DoD): docs/ai-development-framework.md

  • Матрица верификации (какие тесты запускать для каждого типа изменений): docs/verification-matrix.md

  • Журнал архитектурных решений (индекс ADR): docs/architecture-decision-records/README.md

  • Жёсткие ограничения агента на уровне репозитория: AGENTS.md

Related MCP server: MCP Podcast Scraper

Цели проекта

  • Поддержка нескольких подкастов с помощью одного набора основных функций.

  • CLI-скрипты должны только разбирать аргументы и вызывать основные функции.

  • Возможность в будущем упаковать основные возможности непосредственно в MCP tools.

  • Все выходные файлы размещаются в data/ с детерминированными именами для удобства поиска инструментами.

Структура каталогов

config/
  podcasts.yaml
  industry_chain_mappings.yaml
  external_data_boundary.yaml
  external_market_data_fixtures.yaml
  gooaye_lens.yaml
  llm_profiles.yaml
data/
  audio/
  transcripts/
  summaries/
  mentions/
  reports/
  mappings/
  external/
  stock-lens/
  cache/
  corpus/
docs/
  agent-handoff.md
  ai-development-framework.md
  verification-matrix.md
  architecture-decision-records/
  architecture.md
  mvp-requirements.md
  roadmap.md
  mcp-readiness.md
  mcp-usage.md
  codex-mcp-setup.md
  claude-mcp-setup.md
  mcp-troubleshooting.md
scripts/
  list_episodes.py
  download_episode.py
  transcribe_episode.py
  validate_transcript.py
  summarize_episode.py
  run_corpus_episode_intake.py
  generate_corpus_index.py
  generate_corpus_remediation_plan.py
  run_corpus_audio_download.py
  run_corpus_remediation.py
  run_corpus_local_transcription.py
  run_corpus_episode_workflow.py
  run_corpus_semantic_remediation.py
  run_corpus_episode_completion_workflow.py
  run_corpus_latest_episode_deterministic_workflow.py
  run_latest_episode_verified_research_report_workflow.py
  run_episode_verified_research_report_workflow.py
  query_verified_research_report_catalog.py
  revalidate_verified_research_report_sources.py
  query_verified_research_report_coverage.py
  suggest_historical_verified_report_next_step.py
  list_verified_report_gap_backlog.py
  extract_mentions.py
  rebuild_cache.py
  search_transcripts.py
  search_mentions.py
  validate_mcp_setup.py
  validate_hermes_integration.py
  manage_hermes_integration.py
  run_mcp_server.py
  run_mcp_http_server.py
deploy/
  hermes/
src/
  podcast_ingest_core/
tests/

Основные функции

list_episodes(podcast_id, limit)
get_episode(podcast_id, episode_ref)
download_audio(podcast_id, episode_ref)
transcribe_episode(
    podcast_id,
    episode_ref,
    model=None,
    device="cpu",
    compute_type="int8",
    vad_filter=False,
    force=False,
    audio_path=None,
    progress_callback=None,
)
validate_transcript(podcast_id, episode_ref)
summarize_episode(
    podcast_id,
    episode_ref,
    force=False,
    max_quotes=10,
    window_seconds=300,
    allow_partial=False,
)
semantic_summarize_episode(
    podcast_id,
    episode_ref,
    provider="openai-compatible",
    model=None,
    base_url=None,
    api_key_env="OPENAI_API_KEY",
    force=False,
    chunk_seconds=600,
    max_segments_per_chunk=120,
    allow_partial=False,
)
extract_mentions(
    podcast_id,
    episode_ref,
    force=False,
    allow_partial=False,
    max_evidence_per_mention=5,
)
generate_episode_intelligence_report(
    podcast_id,
    episode_ref,
    force=False,
    allow_partial=False,
    window_seconds=300,
    max_evidence_per_section=5,
)
generate_industry_chain_mapping(
    podcast_id,
    episode_ref,
    force=False,
    allow_partial=False,
    max_candidates_per_node=5,
    max_evidence_per_candidate=5,
)
generate_external_data_boundary(
    podcast_id,
    episode_ref,
    force=False,
    allow_partial=False,
)
verify_external_data_boundary(
    podcast_id,
    episode_ref,
    confirm=False,
    force=False,
    allow_partial=False,
    provider="fixture",
    fixture_path=DEFAULT_EXTERNAL_MARKET_DATA_FIXTURE_PATH,
)
load_gooaye_lens_model(path=DEFAULT_GOOAYE_LENS_CONFIG_PATH)
generate_stock_lens_report(
    podcast_id,
    stock_query,
    force=False,
    allow_partial=False,
    max_evidence_items=10,
)
generate_stock_lens_synthesis_report(
    podcast_id,
    stock_query,
    confirm=False,
    force=False,
    allow_partial=False,
    api_cost_ack="",
    provider="openai-compatible",
    model=None,
    base_url=None,
    api_key_env="OPENAI_API_KEY",
    max_prompt_chars=24000,
)
run_research_workflow(
    podcast_id,
    episode_ref,
    stock_query=None,
    confirm=False,
    force=False,
    allow_partial=False,
    include_semantic_summary=False,
    include_stock_lens_synthesis=False,
    include_external_data_verification=False,
    api_cost_ack="",
    semantic_provider="openai-compatible",
    semantic_model=None,
    semantic_base_url=None,
    semantic_api_key_env="OPENAI_API_KEY",
    semantic_chunk_seconds=600,
    semantic_max_segments_per_chunk=120,
    synthesis_provider="openai-compatible",
    synthesis_model=None,
    synthesis_base_url=None,
    synthesis_api_key_env="OPENAI_API_KEY",
    synthesis_max_prompt_chars=24000,
    external_data_provider="fixture",
    external_fixture_path=DEFAULT_EXTERNAL_MARKET_DATA_FIXTURE_PATH,
    max_evidence_per_mention=5,
    report_window_seconds=300,
    max_evidence_per_section=5,
    max_candidates_per_node=5,
    max_evidence_per_candidate=5,
    max_stock_evidence_items=10,
)
initialize_cache(db_path=None)
index_episode(podcast_id, episode_ref, force=False, db_path=None)
rebuild_cache(podcast_id=None, force=False, db_path=None)
search_transcripts(query, podcast_id=None, limit=20, db_path=None, search_mode="auto", context_segments=0, case_sensitive=False)
search_mentions(query, podcast_id=None, mention_type=None, limit=20, db_path=None, case_sensitive=False)
run_corpus_episode_intake(podcast_id, episode_ref="latest", confirm=False)
generate_corpus_index(podcast_id)
generate_corpus_remediation_plan(podcast_id)
run_corpus_audio_download(podcast_id, episode_ref=None, confirm=False)
run_corpus_remediation(
    podcast_id,
    confirm=False,
    episode_ref=None,
    action_family=None,
    max_actions=None,
    force=False,
    allow_partial=False,
)
run_corpus_local_transcription(
    podcast_id,
    episode_ref=None,
    confirm=False,
    model=None,
    device="cpu",
    compute_type="int8",
    vad_filter=False,
)
run_corpus_episode_workflow(
    podcast_id,
    episode_ref="latest",
    stage="next",
    confirm=False,
    model=None,
    device="cpu",
    compute_type="int8",
    vad_filter=False,
    force=False,
    allow_partial=False,
    max_actions=None,
)
run_corpus_semantic_remediation(
    podcast_id,
    episode_ref,
    action="next",
    confirm=False,
    api_cost_ack="",
    provider="openai-compatible",
    model=None,
    base_url=None,
    api_key_env="OPENAI_API_KEY",
    chunk_seconds=600,
    max_segments_per_chunk=120,
    progress_callback=None,
)
run_corpus_episode_completion_workflow(
    podcast_id,
    episode_ref="latest",
    action="next",
    confirm=False,
    api_cost_ack="",
    transcription_model=None,
    transcription_device="cpu",
    transcription_compute_type="int8",
    transcription_vad_filter=False,
    semantic_provider="openai-compatible",
    semantic_model=None,
    semantic_base_url=None,
    semantic_api_key_env="OPENAI_API_KEY",
    semantic_chunk_seconds=600,
    semantic_max_segments_per_chunk=120,
    progress_callback=None,
)
run_corpus_latest_episode_deterministic_workflow(
    podcast_id,
    confirm=False,
    transcription_model=None,
    transcription_device="cpu",
    transcription_compute_type="int8",
    transcription_vad_filter=False,
)
run_latest_episode_verified_research_report_workflow(
    podcast_id,
    confirm=False,
    expected_episode_ref=None,
    api_cost_ack="",
    stock_query=None,
    include_fixture_verification=False,
)
run_episode_verified_research_report_workflow(
    podcast_id,
    episode_ref,
    confirm=False,
    stock_query=None,
    include_fixture_verification=False,
)

summarize_episode — это детерминированный / экстрактивный шаблон, не вызывающий внешний LLM API и не выполняющий семантических выводов. semantic_summarize_episode использует API, совместимый с OpenAI, для создания семантической сводки; к важным выводам следует по возможности прикладывать временные метки, и это не является инвестиционной рекомендацией. extract_mentions использует детерминированные правила для извлечения упоминаний из сегментов транскрипта; каждое упоминание сохраняется с временной меткой. generate_episode_intelligence_report использует детерминированные правила для создания отчёта по эпизоду из существующего транскрипта и артефакта упоминаний; не вызывает LLM, не запрашивает внешние рыночные данные, не создаёт маппинг акций и не даёт инвестиционных рекомендаций. generate_industry_chain_mapping использует локальный детерминированный конфиг маппинга для создания узлов производственной цепочки и кандидатов в акции из существующего отчёта по эпизоду; чётко различает явные доказательства из подкаста и выведенные / требующие проверки исследовательские зацепки. generate_external_data_boundary использует локальный конфиг границ для создания каркаса границ проверки внешних данных из существующего отраслевого маппинга; не вызывает внешних провайдеров, не читает API-ключи и не формирует факты о текущей рыночной ситуации. verify_external_data_boundary — это каркас провайдера фикстур Phase 6M: сначала dry-run; только с confirm=True пытается обновить существующую внешнюю границу с помощью локальных фикстур; имеет защиту confirm, не использует live market API, не вносит изменений в MCP tools и не даёт инвестиционных рекомендаций. load_gooaye_lens_model только загружает и проверяет локальную аналитическую структуру Gooaye Lens; не создаёт отчётов по акциям, не вызывает LLM и не запрашивает внешние рыночные данные. generate_stock_lens_report использует общеподкастовые локальные артефакты и Gooaye Lens для создания структуры исследования акций/компании; не вызывает LLM, не запрашивает внешние рыночные данные, не даёт рекомендаций по покупке/продаже, целевых цен или гарантий доходности. generate_stock_lens_synthesis_report — это Phase 6J Stock Lens LLM Synthesis: сначала dry-run; по умолчанию входная граница LLM — только JSON 6F stock lens; подтверждённое выполнение должно предоставить точный api_cost\_ack; Phase 6V позволяет явно отказаться от проверенного контекста семантической сводки, но по-прежнему не читает сырые транскрипты, не запрашивает внешние рыночные данные, не вносит изменений в MCP tools и не даёт рекомендаций по покупке/продаже. run_research_workflow — это локальный раннер исследовательских процессов с приоритетом dry-run, связывающий упоминания, отчёты по эпизодам, отраслевой маппинг, внешние границы и опционально stock lens; Phase 6I поддерживает опциональное выполнение семантической сводки внутри исследовательского процесса; Phase 6K поддерживает опт-ин синтез в процессе с помощью include_stock_lens_synthesis=True, подключая синтез Phase 6J после отчёта stock lens. Phase 6N поддерживает опциональную проверку фикстур процесса с помощью include_external_data_verification=True, обновляя статус внешней проверки после внешней границы через локального провайдера фикстур; этот шаг не использует live market API, не требует API-ключей, не вносит изменений в MCP tools, не пересобирает кэш автоматически и не даёт инвестиционных рекомендаций. generate_corpus_index только сканирует локальные артефакты по эпизодам и метаданные семантической проверки, записывая детерминированный статус корпуса в JSON/Markdown; не читает RSS, не читает SQLite-кэш, не вызывает LLM, не читает .env, не добавляет MCP tools и не выводит сырые транскрипты/доказательства/семантическое содержимое. generate_corpus_remediation_plan сначала обновляет индекс корпуса, затем выводит из локальных метаданных статуса пробелы полной лестницы, блокировки, предупреждения и текст действий только вручную, записывая детерминированный план исправлений в JSON/Markdown; не выполняет загрузку, транскрибирование, реферирование, процессы, LLM, MCP или пересборку кэша и не выводит сырые транскрипты/доказательства/семантическое содержимое/подсказки/необработанные выходные данные LLM. run_corpus_audio_download сначала обновляет план исправлений; dry-run возвращает только метаданные кандидатов с отсутствующим аудио и готовых к действию, не читает RSS, не вызывает сеть/загрузчик, не пишет отчёт о запуске; подтверждённое выполнение должно указать один эпизод, затем вызывает существующий download_audio() и записывает последний детерминированный отчёт о загрузке аудио, не содержащий исходных URL, строк запросов, секретов или трассировок. run_corpus_remediation сначала обновляет план исправлений; dry-run возвращает только метаданные выбранных/пропущенных/заблокированных/исключённых элементов; подтверждённое выполнение должно указать эпизод или семейство действий и выполняет только детерминированные семейства, готовые к транскрипции (экстрактивная сводка, упоминания, отчёт по эпизоду, отраслевой маппинг, внешняя граница), записывая последний детерминированный отчёт о запуске. run_corpus_local_transcription сначала обновляет план исправлений; dry-run возвращает только метаданные кандидатов с локальным аудио и отсутствующим транскриптом; подтверждённое выполнение должно указать один эпизод и использует только явный локальный audio_path для вызова существующего ядра транскрибирования; не загружает аудио, не исправляет повреждённые/частичные транскрипты, не трогает LLM/MCP/пересборку кэша и записывает последний детерминированный отчёт о локальном транскрибировании. run_corpus_episode_workflow — это безопасная точка входа с приоритетом dry-run для новых эпизодов: последовательно определяет следующий безопасный этап приёма, загрузки аудио, локального транскрибирования и детерминированного исправления; dry-run не пишет отчёт о процессе и не выполняет этапы; подтверждённое выполнение должно использовать stage="next" и выполнять только один этап, записывая последний детерминированный отчёт о процессе. Все шаги LLM требуют confirm=True и точного api_cost_ack перед вызовом внешней LLM. Этот процесс по-прежнему не запрашивает внешние рыночные данные, не передаёт сырые транскрипты в синтез stock lens, не вносит изменений в MCP tools и не пересобирает кэш автоматически. rebuild_cache только индексирует существующие артефакты и не загружает, не транскрибирует, не реферирует, не извлекает упоминания, не создаёт отчёты, маппинги, внешние границы или отчёты stock lens автоматически.

Точный контракт стабилизации 014: confirm=False — это строго нулевой файл; за исключением чтения настроенного RSS-канала подкаста и локальных артефактов, не создаются, не изменяются и не удаляются никакие файлы; выбранная выборка создаёт только один снимок индекса/плана в памяти и последовательно предпросматривает 012/011/010. Это отличается от поведения свежих 008/009, намеренно сохранённого в автономных dry-run 010/011/012.

run_corpus_semantic_remediation(...) — это автономное ядро семантического исправления 015 для одного эпизода. Каждый допустимый запрос создаёт ровно один свежий снимок 008/009 в памяти, сначала изолируя явный канонический эпизод, затем выбирая semantic_summary, semantic_review, completed или заблокированный/ручной; он не вызывает 010 или 014. Dry-run — строго нулевой файл и не разрешает профиль, .env, учётные данные или провайдера. Подтверждённый semantic_summary требует явного действия и проверки точного api_cost_ack до создания профиля/.env/провайдера; подтверждённый semantic_review детерминирован и вообще не читает никаких настроек LLM. Каждый подтверждённый запуск вызывает не более одного исполнителя, записывает подтверждённый отчёт только в формате JSON/Markdown (без generated_at), не пересобирает индекс, план или SQLite-кэш и не добавляет MCP tools; реестр остаётся ровно с 12 инструментами.

run_corpus_episode_completion_workflow(...) — это ядро завершения эпизода 016 для одного эпизода: dry-run со строго нулевым файлом определяет следующее действие от приёма до семантической проверки; после подтверждения человеком выполняет ровно одно соответствующее действие для канонического эпизода и останавливается. Одноимённый инструмент stdio MCP run_corpus_episode_completion_workflow сохраняет эту границу «предпросмотр → одобрение человека → одно действие», не читает .env, не пересобирает кэш автоматически и не даёт инвестиционных рекомендаций.

run_corpus_latest_episode_deterministic_workflow(...) — это ядро 017 для последнего эпизода по одному запросу: dry-run только анализирует текущий последний и возвращает детерминированный план обработки со строго нулевым файлом. SPEC 017 реализован. Проблема сопоставления дочерних результатов seeded/downloaded от 2026-07-17 — это решённый исторический блокер; записанные метаданные подтверждённого эпизода EP679 заканчиваются outcome=ready_for_semantic_summary, ready_count=1, blocked_count=0 и failed_count=0. Контракт фиксирует один канонический эпизод в начале, обрабатывает приём, загрузку, локальное транскрибирование и необходимое детерминированное исправление, завершается сбоем при сбое/блокировке этапа и останавливается на ready_for_semantic_summary без .env, провайдера, семантической сводки/проверки, повторов или пересборки кэша.

run_latest_episode_verified_research_report_workflow(...) — это ядро отчёта исследования последнего эпизода SPEC 018. По умолчанию confirm=False только анализирует последний и возвращает предпросмотр со строго нулевым файлом, не создавая контрольных точек, промежуточных или итоговых пакетов. Подтверждённый запрос должен предоставить точный expected_episode_ref, полученный при предпросмотре, до RSS, окружения/провайдера, записи и дочерних этапов, а также точно такой же api_cost_ack; он повторно использует закреплённую детерминированную лестницу 017 и после точного прохождения passed семантической сводки/проверки создаёт детерминированный JSON, Markdown и манифест с фиксированными безопасными параметрами исследования. Пакет использует версионирование по дайджесту контента, атомарную публикацию каталога, повторное использование идентичного содержимого и конфликт-фейл-закрытие; не пересобирает кэш автоматически, не запрашивает live market API и не является инвестиционной рекомендацией.

run_episode_verified_research_report_workflow(...) — это ядро отчёта исследования для явного эпизода SPEC 019. Требуется явный episode_ref (может быть историческим; latest/next отклоняются); предпросмотр только проверяет локальную готовность и не записывает файлы; подтверждение собирает/публикует пакет с дайджестом, эквивалентным 018, только если происхождение и проверка пройдены; api_cost_ack не требуется, LLM/RSS/загрузка не вызываются, 015–017 не связываются. При отсутствии компонентов возвращается blocked с перечислением отсутствующих/устаревших ролей.

SPEC 020 предоставляет офлайн-каталог-ориентированные слоты list_verified_research_reports(...), search_verified_research_reports(...) и inspect_verified_research_report(...) только для чтения. Они перечисляют, ищут безопасные метаданные из манифеста или проверяют локальную самосогласованность точного пакета; не выполняют поиск по телу, не возвращают необработанные манифесты или абсолютные пути, не экспортируют, не используют БД/FTS/вектор/кэш, не используют сеть/LLM и не заявляют об актуальности/свежести источника. Inspect всегда возвращает source_currentness_status=not_evaluated.

SPEC 022 предоставляет list_verified_research_report_coverage(podcast_id, *, has_bundle=None, limit=50): выполняет эпизодо-центричное соединение покрытия локальной инвентаризации × проверенных пакетов отчётов для точного подкаста, опционально перечисляя только эпизоды без пакета или с пакетом; офлайн / без записи / не читает тело отчёта, не выполняет повторную проверку источника и не заявляет об актуальности.

validate_transcript можно использовать для проверки того, является ли стенограмма полной, пустой, частично завершённой, отсутствующей или повреждённой.

run_corpus_episode_intake — это раннер начальной загрузки эпизодов RSS с приоритетом dry-run: dry-run может анализировать latest или один явный селектор эпизода, но не записывает файлы, не загружает, не транскрибирует и не трогает LLM/MCP/кэш; подтверждённое выполнение записывает только безопасные начальные метаданные и последний детерминированный отчёт о приёме, чтобы 008/009/012 могли обнаруживать, планировать и загружать аудио.

Правила выходных путей

Все артефакты находятся в data/:

  • Аудио: data/audio/{podcast_id}/{episode_ref}__{safe_title_slug}.{ext}

  • Транскрипт: data/transcripts/{podcast_id}/{episode_ref}__{safe_title_slug}.txt

  • Субтитры: data/transcripts/{podcast_id}/{episode_ref}__{safe_title_slug}.srt

  • Метаданные транскрипта: data/transcripts/{podcast_id}/{episode_ref}__{safe_title_slug}.json

  • Сводка: data/summaries/{podcast_id}/{episode_ref}__{safe_title_slug}.md

  • Семантическая сводка: data/summaries/{podcast_id}/{episode_ref}__{safe_title_slug}.semantic.md

  • Mentions JSON: data/mentions/{podcast_id}/{episode_ref}__{safe_title_slug}.mentions.json

  • Mentions Markdown: data/mentions/{podcast_id}/{episode_ref}__{safe_title_slug}.mentions.md

  • Episode intelligence JSON: data/reports/{podcast_id}/{episode_ref}__{safe_title_slug}.intelligence.json

  • Episode intelligence Markdown: data/reports/{podcast_id}/{episode_ref}__{safe_title_slug}.intelligence.md

  • Industry mapping JSON: data/mappings/{podcast_id}/{episode_ref}__{safe_title_slug}.industry-map.json

  • Industry mapping Markdown: data/mappings/{podcast_id}/{episode_ref}__{safe_title_slug}.industry-map.md

  • External data boundary JSON: data/external/{podcast_id}/{episode_ref}__{safe_title_slug}.external-boundary.json

  • External data boundary Markdown: data/external/{podcast_id}/{episode_ref}__{safe_title_slug}.external-boundary.md

  • Stock lens JSON: data/stock-lens/{podcast_id}/{safe_stock_query}.stock-lens.json

  • Stock lens Markdown: data/stock-lens/{podcast_id}/{safe_stock_query}.stock-lens.md

  • Stock lens synthesis JSON: data/stock-lens/{podcast_id}/{safe_stock_query}.stock-lens-synthesis.json

  • Stock lens synthesis Markdown: data/stock-lens/{podcast_id}/{safe_stock_query}.stock-lens-synthesis.md

  • Corpus index JSON: data/corpus/{podcast_id}/corpus-index.json

  • Corpus index Markdown: data/corpus/{podcast_id}/corpus-index.md

  • Corpus episode seed JSON: data/corpus/{podcast_id}/episode-seeds/{episode_ref}.episode-seed.json

  • Corpus episode intake run JSON: data/corpus/{podcast_id}/corpus-episode-intake-run.json

  • Corpus episode intake run Markdown: data/corpus/{podcast_id}/corpus-episode-intake-run.md

  • Corpus remediation plan JSON: data/corpus/{podcast_id}/corpus-remediation-plan.json

  • Corpus remediation plan Markdown: data/corpus/{podcast_id}/corpus-remediation-plan.md

  • Corpus remediation run JSON: data/corpus/{podcast_id}/corpus-remediation-run.json

  • Corpus remediation run Markdown: data/corpus/{podcast_id}/corpus-remediation-run.md

  • Corpus local transcription run JSON: data/corpus/{podcast_id}/corpus-local-transcription-run.json

  • Corpus local transcription run Markdown: data/corpus/{podcast_id}/corpus-local-transcription-run.md

  • Corpus audio download run JSON: data/corpus/{podcast_id}/corpus-audio-download-run.json

  • Corpus audio download run Markdown: data/corpus/{podcast_id}/corpus-audio-download-run.md

  • Corpus episode workflow run JSON: data/corpus/{podcast_id}/corpus-episode-workflow-run.json

  • Corpus episode workflow run Markdown: data/corpus/{podcast_id}/corpus-episode-workflow-run.md

  • Corpus semantic remediation run JSON: data/corpus/{podcast_id}/corpus-semantic-remediation-run.json

  • Corpus semantic remediation run Markdown: data/corpus/{podcast_id}/corpus-semantic-remediation-run.md

  • Corpus episode completion workflow run JSON: data/corpus/{podcast_id}/corpus-episode-completion-workflow-run.json

  • Corpus episode completion workflow run Markdown: data/corpus/{podcast_id}/corpus-episode-completion-workflow-run.md

  • Corpus latest deterministic workflow run JSON: data/corpus/{podcast_id}/corpus-latest-episode-deterministic-workflow-run.json

  • Corpus latest deterministic workflow run Markdown: data/corpus/{podcast_id}/corpus-latest-episode-deterministic-workflow-run.md

  • Verified research checkpoint: data/corpus/{podcast_id}/verified-research/{episode_ref}.checkpoint.json

  • Verified research report bundle: data/research-reports/{podcast_id}/{episode_ref}/v1-{source_digest}/report.json, report.md, manifest.json

  • SQLite metadata cache: data/cache/podcast_ingest.sqlite3

  • Episode cache: data/cache/{podcast_id}/episodes.json

podcast_id должен быть slug в нижнем регистре. Episode ref разрешается из RSS title и default_episode_prefix профиля подкаста, например EP672. Title slug в имени файла удаляет недопустимые в Windows символы, управляющие символы, эмодзи и символы высокого риска.

Примеры CLI

Создание corpus status index уровня подкаста:

python scripts/generate_corpus_index.py --podcast gooaye

Этот CLI читает только локальные per-episode артефакты и перезаписывает data/corpus/{podcast_id}/corpus-index.json и .md. stdout — это metadata-only JSON, содержащий пути вывода, количество эпизодов, количество предупреждений и количество по семействам артефактов; он не содержит исходного текста транскрипта, фрагментов evidence, тела семантической сводки, промптов, raw LLM output, API-ключей или секретов провайдера.

Создание corpus remediation plan уровня подкаста:

python scripts/generate_corpus_remediation_plan.py --podcast gooaye

Этот CLI сначала обновляет corpus index, затем перезаписывает data/corpus/{podcast_id}/corpus-remediation-plan.json и .md. stdout — это metadata-only JSON, содержащий пути вывода, количество эпизодов, количество предупреждений, количество действий, а также количество заблокированных/необязательных/условных действий; он не выполняет никаких remediation-действий, не читает RSS/SQLite cache/.env, не вызывает network/LLM/MCP и не выводит transcript/evidence/semantic body/prompt/raw LLM output или секреты.

Предпросмотр или подтверждённое выполнение загрузки аудио одного эпизода:

python scripts/run_corpus_audio_download.py --podcast gooaye
python scripts/run_corpus_audio_download.py --podcast gooaye --episode EP672 --confirm

Этот CLI сначала обновляет corpus remediation plan; поэтому отдельный dry-run всё равно сохраняет свежие corpus index и remediation plan. По умолчанию dry-run возвращает в stdout только metadata-only JSON, не читает RSS, не вызывает network/downloader, не пишет corpus-audio-download-run.json/.md и не пишет аудио. --confirm должен использоваться ровно с одним --episode и вызывает существующую download_audio() только если audio status равен missing, а audio action — ready. Подтверждённый запуск записывает последние data/corpus/{podcast_id}/corpus-audio-download-run.json и .md; содержимое не содержит timestamp, source URL/query string, секретов и traceback и не является инвестиционной рекомендацией; после записи или повторного использования аудио он лишь сообщает, что транскрибация, нижестоящие remediation и пересборка кэша должны быть выполнены вручную.

Предпросмотр или подтверждённое выполнение детерминированного исправления корпуса:

python scripts/run_corpus_remediation.py --podcast gooaye
python scripts/run_corpus_remediation.py --podcast gooaye --action-family mentions --confirm
python scripts/run_corpus_remediation.py --podcast gooaye --episode EP672 --confirm

Этот CLI сначала обновляет corpus remediation plan; поэтому отдельный dry-run всё равно сохраняет свежие corpus index и remediation plan. По умолчанию dry-run возвращает в stdout только metadata-only JSON, не пишет corpus-remediation-run.json/.md и не запускает генераторы артефактов. --confirm должен использоваться с --episode или --action-family; он вызывает только существующие детерминированные основные функции и не выполняет shell-вызовы скриптов; v1 не выполняет download, transcribe, semantic summary/review, stock-lens, LLM, RSS/network, пересборку SQLite cache, .env или MCP. Подтверждённый запуск записывает последние data/corpus/{podcast_id}/corpus-remediation-run.json и .md; содержимое не содержит timestamp, raw transcript/evidence/semantic body/prompt/raw LLM output/secret и не является инвестиционной рекомендацией.

Предпросмотр или подтверждённое выполнение локальной транскрибации одного эпизода:

python scripts/run_corpus_local_transcription.py --podcast gooaye
python scripts/run_corpus_local_transcription.py --podcast gooaye --episode EP672 --confirm
python scripts/run_corpus_local_transcription.py --podcast gooaye --episode EP672 --confirm --model small --device cuda --compute-type float16

Этот CLI сначала обновляет corpus remediation plan; поэтому отдельный dry-run всё равно сохраняет свежие corpus index и remediation plan. По умолчанию dry-run возвращает в stdout только metadata-only JSON, не пишет corpus-local-transcription-run.json/.md, не пишет транскрипт, не загружает модель Whisper и не скачивает аудиофайл. --confirm должен использоваться ровно с одним --episode и вызывает существующую transcribe_episode() только если локальный путь к аудио существует, а статус транскрипта — missing, при этом явно передаются audio_path и force=False. Подтверждённый запуск записывает последние data/corpus/{podcast_id}/corpus-local-transcription-run.json и .md; содержимое не содержит timestamp, raw transcript/prompt/raw LLM output/secret/traceback и не является инвестиционной рекомендацией; после записи транскрипта он лишь предупреждает, что кэш может быть устаревшим, и не пересобирает кэш автоматически.

Предпросмотр или подтверждённое выполнение следующего безопасного этапа свежего workflow эпизода:

python scripts/run_corpus_episode_workflow.py --podcast gooaye --episode latest
python scripts/run_corpus_episode_workflow.py --podcast gooaye --episode latest --stage next --confirm
python scripts/run_corpus_episode_workflow.py --podcast gooaye --episode EP677 --stage next --confirm --model small --device cuda --compute-type float16

Dry-run 014 в этом CLI — strict zero-file: 013 может читать настроенный RSS-селектор разбора; при наличии seed он лишь один раз создаёт свежий in-memory snapshot corpus index/plan и использует этот же snapshot для preview 012/011/010. Он не создаёт, не изменяет и не удаляет seed, audio, transcript, index, plan, отчёты 010-014, downstream-артефакты или .part; planned reads могут включать безопасные локальные пути зависимостей, а для не-путевых значений допускаются только две точные метки. Подтверждённое выполнение должно явно использовать --stage next --confirm и каждый раз диспатчит только один существующий public runner; этот runner может согласно своему контракту обновить index/plan и записать артефакты выбранного этапа, а 014 после записи результата останавливается и пишет последний workflow report. Задачи semantic/LLM/stock-lens/MCP/cache rebuild/batch по-прежнему перечислены только как ручные follow-up и автоматически не выполняются.

Предпросмотр или подтверждённое выполнение семантического исправления одного эпизода:

python scripts/run_corpus_semantic_remediation.py --podcast gooaye --episode EP700
python scripts/run_corpus_semantic_remediation.py --podcast gooaye --episode EP700 --action semantic_summary --confirm --api-cost-ack "I understand this may call an external LLM API, send transcript text outside this machine, and incur costs."
python scripts/run_corpus_semantic_remediation.py --podcast gooaye --episode EP700 --action semantic_review --confirm

015 не принимает latest; dry-run action=next возвращает только метаданные и является strict zero-file. Для подтверждённой сводки точный api_cost_ack должен быть указан до создания profile, .env, credential и provider; для review подтверждение не требуется, и он не резолвит profile/.env и не вызывает LLM. Валидированная подтверждённая попытка записывает corpus-semantic-remediation-run.json/.md; содержимое не содержит generated_at, transcript/semantic/prompt/raw response/base URL/secret/traceback; index, plan и cache могут быть устаревшими, их нужно обновить вручную.

Предпросмотр или выполнение completion workflow одного эпизода после явного подтверждения пользователя:

python scripts/run_corpus_episode_completion_workflow.py --podcast gooaye
python scripts/run_corpus_episode_completion_workflow.py --podcast gooaye --episode EP677 --action audio_download --confirm
python scripts/run_corpus_episode_completion_workflow.py --podcast gooaye --episode EP677 --action semantic_summary --confirm --api-cost-ack "I understand this may call an external LLM API, send transcript text outside this machine, and incur costs."

Dry-run 016 — strict zero-file: при наличии seed он создаёт в памяти только один свежий snapshot 008/009 и последовательно выбирает следующее безопасное действие среди intake, audio download, local transcription, deterministic remediation, semantic summary или semantic review. Подтверждённый запуск должен использовать canonical episode, возвращённый dry-run, и то же самое explicit action; next, latest или устаревшие действия отклоняются, и после каждого запуска диспатчится не более одного существующего runner, затем выполнение останавливается. Точный ack для semantic summary должен быть завершён до любой работы с profile/.env/provider; semantic review не читает настройки LLM. Только валидированная подтверждённая попытка атомарно записывает data/corpus/{podcast_id}/corpus-episode-completion-workflow-run.json и .md; index, plan или SQLite cache автоматически не обновляются.

Если это делает Agent, используйте одноимённый MCP tool run_corpus_episode_completion_workflow и портативный Skill corpus-episode-completion из репозитория: сначала preview, объясните риски, дождитесь явного согласия человека на canonical action, затем выполните одно действие и остановитесь; при отсутствии MCP нельзя переключаться на CLI, terminal, scheduler или автоматические повторы.

Предпросмотр или контролируемое подтверждённое выполнение latest deterministic workflow:

python scripts/run_corpus_latest_episode_deterministic_workflow.py --podcast gooaye
python scripts/run_corpus_latest_episode_deterministic_workflow.py --podcast gooaye --confirm

SPEC 017 реализован. Если Agent получает явный запрос вроде «помоги мне обработать последний эпизод Gooaye», Skill corpus-latest-episode-processing рассматривает этот явный запрос на естественном языке как одну авторизацию выполнения: подтвердите один раз, вызовите dedicated MCP tool run_corpus_latest_episode_deterministic_workflow ровно один раз с confirm=true, однократно сообщите metadata-only result и остановитесь. Сам MCP tool по-прежнему по умолчанию работает в режиме dry-run с confirm=false; Skill не должен сначала делать preview, не должен делать повторный вызов, а также не должен использовать CLI/terminal fallback, планировщик, пакетный режим, повторы, cache rebuild или semantic summary/review.

Предпросмотр workflow последнего verified research report:

python scripts/run_latest_episode_verified_research_report_workflow.py --podcast gooaye

Preview в SPEC 018 — strict zero-write и возвращает canonical episode reference и точное требуемое подтверждение. Только после явного согласия пользователя на этот previewed episode выполняется один --confirm с тем же --expected-episode-ref и точным --api-cost-ack. Подтверждение должно произойти до работы с RSS, environment/provider, writer или child stage; workflow переиспользует закреплённую детерминированную лестницу, требует exact passed от semantic review, а затем завершает детерминированное исследование с фиксированными безопасными опциями. По завершении атомарно публикуются report.json, report.md и manifest.json с версией source digest; повторное использование идентичного бандла, при конфликте — fail-closed; никаких retry, scheduler, live market API или cache rebuild, и это не является инвестиционной рекомендацией.

Запрос к offline read-only каталогу verified research report (SPEC 020):

python scripts/query_verified_research_report_catalog.py list --podcast-id gooaye --limit 50
python scripts/query_verified_research_report_catalog.py search "EP672" --podcast-id gooaye
python scripts/query_verified_research_report_catalog.py inspect gooaye EP672 <lowercase-64-hex-source-digest>

Эти три subcommand читают только канонические локальные manifest-first бандлы из data/research-reports: list поддерживает точные фильтры, search ищет только по безопасным метаданным, inspect проверяет только локальную самосогласованность одного точного бандла. Они не ищут по телу report/transcript, не возвращают raw manifest/absolute paths, не предоставляют export и не используют DB/FTS/vector/cache, RSS/HTTP/network, LLM, .env, download, transcription или remediation; не принимают latest selector и не делают заявлений о latest/currentness источника. inspect всегда возвращает source_currentness_status=not_evaluated. Краткая граница: нет raw manifest; нет DB/FTS/vector/cache; нет RSS/HTTP/LLM/.env/download/transcription/remediation; нет latest selector.

Запрос покрытия verified research report по эпизодам (SPEC 022):

python scripts/query_verified_research_report_coverage.py gooaye
python scripts/query_verified_research_report_coverage.py gooaye --has-bundle false --limit 20

Выполняется join локального inventory и canonical bundles: находятся эпизоды, у которых отсутствует report, или эпизоды, у которых уже есть digest. offline / zero-write / не читает тело report; не перезапускает 021 revalidation и не заявляет source currentness.

Список последних эпизодов:

python scripts/list_episodes.py --podcast gooaye --limit 10
python scripts/list_episodes.py --podcast gooaye --episode latest

Скачать аудиофайл:

python scripts/download_episode.py --podcast gooaye --episode latest

Для транскрибации на CPU рекомендуется сначала проверить процесс на моделях tiny или base:

python scripts/transcribe_episode.py --podcast gooaye --episode latest --model tiny --device cpu --compute-type int8

Полный длинный эпизод на CPU может занять очень много времени. Если нужно лишь убедиться, что faster-whisper, ffmpeg/PyAV и процесс вывода работают, можно использовать короткий аудиофайл для smoke test:

python scripts/transcribe_episode.py --audio-path path\to\sample.mp3 --podcast gooaye --episode smoke-test --model tiny --device cpu --compute-type int8 --force

Если есть NVIDIA GPU, при поддержке CUDA окружением можно попробовать:

python scripts/transcribe_episode.py --podcast gooaye --episode latest --model small --device cuda --compute-type float16

Рекомендуемый процесс для длинных аудиофайлов:

python scripts/transcribe_episode.py --podcast gooaye --episode latest --model tiny --device cpu --compute-type int8
python scripts/validate_transcript.py --podcast gooaye --episode latest
python scripts/summarize_episode.py --podcast gooaye --episode latest --force

На CPU обработка 50-минутного аудио может быть медленной. tiny / base подходят для первичной проверки процесса, small / medium можно использовать для повышения качества. При наличии NVIDIA GPU можно попробовать --device cuda --compute-type float16. Если после timeout остаётся высоконагружающий CPU процесс Python, сначала остановите этот процесс вручную, затем запустите заново.

Создать детерминированную Markdown-сводку:

python scripts/summarize_episode.py --podcast gooaye --episode smoke-test --mode extractive --force
python scripts/summarize_episode.py --podcast gooaye --episode EP672 --mode extractive --max-quotes 5 --window-seconds 300

Сводка читает только существующий transcript и не скачивает и не транскрибирует автоматически. Если для указанного эпизода ещё нет transcript, CLI сообщит transcript missing. Если transcript является partial, сводка по умолчанию отклонит его; чтобы всё же создать сводку, можно добавить --allow-partial.

Для создания LLM semantic summary требуются API key и model. Для ручного тестирования рекомендуется использовать локальный .env; этот файл игнорируется .gitignore и не может быть закоммичен:

API_KEY=your-api-key
MODEL=your-model
BASE_URL=https://api.openai.com/v1
python scripts/summarize_episode.py --podcast gooaye --episode EP672 --mode semantic --force --api-cost-ack "I understand this may call an external LLM API, send transcript text outside this machine, and incur costs."

Можно также переопределить настройки напрямую через CLI:

python scripts/summarize_episode.py --podcast gooaye --episode EP672 --mode semantic --model your-model --base-url https://api.openai.com/v1 --api-cost-ack "I understand this may call an external LLM API, send transcript text outside this machine, and incur costs."

Режим semantic сначала выполняет проверку транскрипта (transcript validation) и отправляет транскрипт провайдеру порциями по умолчанию 600 секунд и 120 сегментов на chunk. CLI, работающий с LLM, по умолчанию загружает .env; можно указать другой файл с помощью --env-file path\to\.env или отключить загрузку с помощью --no-env-file. Если переменная с одинаковым именем есть и в .env, и в сессии PowerShell, приоритет имеет сессия PowerShell. MODEL / BASE_URL — рекомендуемые имена; если они не заданы, для совместимости будут читаться старые OPENAI_MODEL / OPENAI_BASE_URL. Если отсутствует API key или model, CLI чётко сообщит об ошибке конфигурации; режиму extractive API key не требуется. Семантическое резюме не является инвестиционной рекомендацией; все важные рыночные мнения, компании, лица и события должны по возможности опираться на timestamp evidence.

Phase 6U добавляет smoke-валидацию семантического резюме. Этот путь при confirmed execution отправляет текст транскрипта за пределы этой машины; dry-run только перечисляет planned reads/writes, риск передачи транскрипта, ценовой риск и required acknowledgement, не вызывает LLM, не записывает артефакты и не выводит содержимое транскрипта. Confirmed semantic summary smoke, а также прямой CLI-вызов --mode semantic должны предоставлять точный api_cost_ack. stdout CLI остаётся без вывода raw transcript и без отображения секретных значений; на этом этапе — no MCP tool changes, no live market API, no automatic cache rebuild, no investment advice.

Phase 6U.1 исправляет ложное срабатывание semantic review guard: semantic summary review допускает описания, производные от транскрипта, такие как прошлые покупки/удержание спикером в содержании подкаста, но по-прежнему отклоняет прямые buy/sell/hold, рекомендации покупать, целевые цены и гарантированную доходность. Confirmed semantic smoke также добавляет прогресс в stderr; stdout остаётся JSON, и прогресс не выводит raw transcript, prompt, API key или ответ LLM. Phase 6V добавляет опциональный проверенный семантический контекст (reviewed semantic context) для синтеза stock lens. Синтез по умолчанию остаётся phase-6f-stock-lens-json-only и не читает .semantic.md. При явном включении с помощью --include-semantic-context синтез может включать только совпавшие семантические резюме эпизодов с последним пройденным отчётом проверки; граница входных данных становится phase-6f-stock-lens-json-plus-reviewed-semantic-summary. Контекст исключает ## Chunk Summaries, не читает raw-текст транскрипта, не читает .env, не получает данные живого рынка и не вносит изменений в MCP tools. Проверенный контекст семантического резюме — это промежуточный артефакт LLM, а не raw-доказательство из подкаста и не внешний рыночный факт. Phase 6V.1 приводит детерминированный шлюз проверки в соответствие с согласованностью границ/контекста: синтез только из JSON не должен иметь семантического контекста, а проверенный семантический синтез должен включать непустой семантический контекст, прошедший проверку.

python scripts/run_research_llm_smoke.py --podcast gooaye --episode EP672 --stock 台積電 --llm-profile pro4500 --confirm --force --include-semantic-context --api-cost-ack "I understand this may call an external LLM API, send transcript text outside this machine, and incur costs."

Профиль LLM provider можно разместить в config/llm_profiles.yaml; он хранит только provider, model, base URL и имя переменной окружения для API key, но не значение API key. Рабочий профиль pro4500 использует api_key_env=API_KEY, поэтому его можно использовать вместе с API_KEY=... из .env. Зафиксированный профиль gb10 помечен как unavailable; при загрузке произойдёт ошибка с подсказкой использовать pro4500. Не записывайте API key, token или secret в YAML.

Извлечение детерминированных mentions:

python scripts/extract_mentions.py --podcast gooaye --episode EP672 --force
python scripts/extract_mentions.py --podcast gooaye --episode EP672 --max-evidence-per-mention 3

Mention extraction не использует LLM и не означает полного семантического понимания; он лишь сканирует сегменты транскрипта по детерминированным правилам на предмет mentions компаний, ticker, отраслей, макроэкономических тем, crypto и мест. Каждый mention сопровождается timestamp evidence и не является инвестиционной рекомендацией. Кэш Phase 3 может импортировать mentions в SQLite и предоставлять базовые межэпизодные запросы; в будущем MCP tools смогут напрямую оборачивать эти core functions.

Создание детерминированного отчёта об эпизоде (episode intelligence report):

python scripts/generate_episode_intelligence_report.py --podcast gooaye --episode EP672 --force
python scripts/generate_episode_intelligence_report.py --podcast gooaye --episode EP672 --window-seconds 600 --max-evidence-per-section 3

Episode intelligence report читает только существующие артефакты transcript и mentions; он не загружает, не транскрибирует, не резюмирует, не извлекает mentions, не вызывает LLM и не запрашивает внешние рыночные данные. Если артефакт mentions отсутствует, отчёт всё равно может быть создан, но будет помечен source warning, а разделы, производные от mentions, останутся пустыми. Partial transcript по умолчанию отклоняется; чтобы всё же создать черновик, можно добавить --allow-partial.

Создание детерминированного сопоставления отраслевых цепочек / кандидатов в акции:

python scripts/generate_industry_chain_mapping.py --podcast gooaye --episode EP672 --force
python scripts/generate_industry_chain_mapping.py --podcast gooaye --episode EP672 --max-candidates-per-node 3 --max-evidence-per-candidate 2

Industry mapping читает только существующий episode intelligence report и config/industry_chain_mappings.yaml; он не вызывает LLM и не запрашивает внешние рыночные данные. podcast_explicit означает, что это явно упомянуто в podcast evidence; inferred_from_industry представляет лишь непроверенную исследовательскую зацепку, выведенную из локального mapping config, по умолчанию needs_verification, и не означает, что 股癌 явно упомянул это, а также не является инвестиционной рекомендацией.

Создание каркаса границы внешних рыночных данных:

python scripts/generate_external_data_boundary.py --podcast gooaye --episode EP672 --force
python scripts/generate_external_data_boundary.py --podcast gooaye --episode EP672 --allow-partial

External data boundary читает только существующий industry mapping и config/external_data_boundary.yaml; он не вызывает внешних провайдеров рыночных данных, не читает API key и не формирует факты о ценах, рыночной капитализации, финансовой отчётности, новостях или текущем состоянии компаний. Каждый candidate помечается external_verification_status=not_requested, source_status=not_fetched и data_date=null, а также перечисляются типы внешних данных, которые потребуется проверить в дальнейшем.

Проверка external boundary с помощью локального fixture provider:

python scripts/verify_external_data_boundary.py --podcast gooaye --episode EP672
python scripts/verify_external_data_boundary.py --podcast gooaye --episode EP672 --confirm --force
python scripts/verify_external_data_boundary.py --podcast gooaye --episode EP672 --confirm --fixture-path config/external_market_data_fixtures.yaml

Phase 6M предоставляет только каркас fixture provider. По умолчанию dry-run не записывает артефакты; --confirm — это confirm guard, после подтверждения читается только локальный config/external_market_data_fixtures.yaml или указанный путь к fixture, выполняется точное сопоставление по company_name / ticker и обновляются существующие .external-boundary.json/.md. На этом этапе — no live market API, не читается API key, не добавляются MCP tools, не подключается research workflow, и не предоставляются никакие рыночные рекомендации, кроме no investment advice.

Проверка модели Gooaye Lens:

python scripts/inspect_gooaye_lens.py
python scripts/inspect_gooaye_lens.py --path config/gooaye_lens.yaml

Модель Gooaye Lens — источник детерминированной аналитической структуры для stock lens report Phase 6F; она определяет такие измерения, как положение в отраслевой цепочке, спрос/предложение и запасы, экономический цикл, чувствительность к процентным ставкам и оценке, капитальные расходы и мощности, геополитика и неопределённость. Phase 6E только загружает и проверяет локальный config; он не принимает ввод акций, не записывает артефакты, не вызывает LLM, не запрашивает внешние рыночные данные и не формирует рекомендации по покупке/продаже, целевые цены или гарантированную доходность.

Создание детерминированного stock lens report по всему подкасту:

python scripts/generate_stock_lens_report.py --podcast gooaye --stock 台積電 --force
python scripts/generate_stock_lens_report.py --podcast gooaye --stock NVDA --max-evidence-items 5

Stock lens report сканирует существующие артефакты data/mappings/ и data/external/ этого подкаста и консервативно сопоставляет company_name и tickers кандидатов. podcast_explicit указывается как direct podcast evidence; inferred_from_industry указывается только как needs-verification research lead и не означает, что подкаст явно упомянул это. Если direct podcast evidence отсутствует, отчёт всё равно создаётся и явно помечается no-direct-podcast-evidence. На этом этапе не вызывается LLM, не запрашиваются внешние рыночные данные, не читается API key, не добавляются MCP tools и не предоставляются рекомендации по покупке/продаже, целевые цены или гарантированная доходность.

Создание Phase 6J Stock Lens LLM Synthesis:

python scripts/generate_stock_lens_synthesis_report.py --podcast gooaye --stock 台積電
python scripts/generate_stock_lens_synthesis_report.py --podcast gooaye --stock 台積電 --confirm --api-cost-ack "I understand this may call an external LLM API, send transcript text outside this machine, and incur costs." --model your-model
python scripts/generate_stock_lens_synthesis_report.py --podcast gooaye --stock 台積電 --llm-profile pro4500 --confirm --api-cost-ack "I understand this may call an external LLM API, send transcript text outside this machine, and incur costs."

Stock lens synthesis по умолчанию работает в режиме dry-run, перечисляя только planned reads/writes, LLM API/cost risk и required acknowledgement; он не читает API key, не вызывает LLM и не записывает артефакты. Confirmed execution передаёт LLM только compact evidence, lens dimensions, external boundary status и warnings из 6F stock lens JSON only; no raw transcript, no .semantic.md input, no external market data lookup, no MCP tool changes, и не подключается run_research_workflow. Если вывод LLM содержит формулировки инвестиционных рекомендаций, такие как buy/sell/hold, target price или guaranteed return, запись в synthesis artifact будет отклонена.

Выполнение Phase 6O LLM research smoke:

python scripts/run_research_llm_smoke.py --podcast gooaye --episode EP672 --stock 台積電 --model your-model
python scripts/run_research_llm_smoke.py --podcast gooaye --episode EP672 --stock 台積電 --confirm --api-cost-ack "I understand this may call an external LLM API, send transcript text outside this machine, and incur costs." --model your-model --force
python scripts/run_research_llm_smoke.py --podcast gooaye --episode EP672 --stock 台積電 --llm-profile pro4500 --confirm --api-cost-ack "I understand this may call an external LLM API, send transcript text outside this machine, and incur costs." --force --debug-llm-output
python scripts/run_research_llm_smoke.py --podcast gooaye --episode EP672 --stock 台積電 --confirm --include-semantic-summary --api-cost-ack "I understand this may call an external LLM API, send transcript text outside this machine, and incur costs." --model your-model --force

Phase 6O — это OpenAI-compatible smoke + Codex manual review harness. Реальные вызовы LLM по-прежнему идут через OpenAI-compatible /chat/completions; в настоящее время нет прямого backend для Codex-сессии, и Codex выступает только как manual reviewer, проверяющий артефакты, границы prompt и качество. Smoke по умолчанию запускает stock lens synthesis с включённой fixture external verification; semantic summary требует явного добавления --include-semantic-summary, поскольку он передаёт текст транскрипта. На этом этапе — no live market data, не добавляются MCP tools, не изменяется investment-advice boundary, и сохраняется no investment advice. Phase 6Q добавляет конфигурацию LLM profile; для ручного тестирования можно использовать --llm-profile pro4500 для чтения config/llm_profiles.yaml. Явно переданные в CLI --model, --base-url, --api-key-env переопределяют profile; YAML не должен содержать значения API key, token или secret. Phase 6R добавляет локальный загрузчик .env; CLI, работающий с LLM, по умолчанию читает API_KEY, MODEL, BASE_URL из .env и отображает в JSON metadata только имена загруженных env var, но не их значения. Для диагностики ответа провайдера можно добавить --debug-llm-output; raw LLM output записывается только в evals/research-llm-smoke/raw/, который игнорируется .gitignore, и не становится официальным артефактом. Phase 6T добавляет детерминированный review report / quality gate. После confirmed smoke можно сгенерировать review report с меткой времени следующей командой; он читает только существующие артефакты — no LLM call, no .env read, no external market data — и не перезаписывает synthesis artifacts:

python scripts/review_research_llm_smoke.py --podcast gooaye --episode EP672 --stock 台積電

Документация LLM smoke и шаблон review:

python scripts/run_semantic_summary_smoke.py --podcast gooaye --episode EP672 --llm-profile pro4500
python scripts/run_semantic_summary_smoke.py --podcast gooaye --episode EP672 --llm-profile pro4500 --confirm --force --api-cost-ack "I understand this may call an external LLM API, send transcript text outside this machine, and incur costs."
python scripts/review_semantic_summary_smoke.py --podcast gooaye --episode EP672

Dry-run или выполнение локального детерминированного research workflow:

python scripts/run_research_workflow.py --podcast gooaye --episode EP672
python scripts/run_research_workflow.py --podcast gooaye --episode EP672 --confirm
python scripts/run_research_workflow.py --podcast gooaye --episode EP672 --confirm --stock 台積電
python scripts/run_research_workflow.py --podcast gooaye --episode EP672 --include-semantic-summary
python scripts/run_research_workflow.py --podcast gooaye --episode EP672 --confirm --include-semantic-summary --api-cost-ack "I understand this may call an external LLM API, send transcript text outside this machine, and incur costs." --semantic-model your-model
python scripts/run_research_workflow.py --podcast gooaye --episode EP672 --include-external-data-verification
python scripts/run_research_workflow.py --podcast gooaye --episode EP672 --confirm --include-external-data-verification --external-fixture-path config/external_market_data_fixtures.yaml
python scripts/run_research_workflow.py --podcast gooaye --episode EP672 --stock 台積電 --include-stock-lens-synthesis
python scripts/run_research_workflow.py --podcast gooaye --episode EP672 --confirm --stock 台積電 --include-stock-lens-synthesis --api-cost-ack "I understand this may call an external LLM API, send transcript text outside this machine, and incur costs." --synthesis-model your-model

Research workflow сначала выполняет dry-run, перечисляя planned reads/writes, порядок шагов, риск внешнего API для semantic LLM, риск устаревшего кэша и статус подтверждения. По умолчанию выполняются только локальные детерминированные шаги: extract_mentions, generate_episode_intelligence_report, generate_industry_chain_mapping, generate_external_data_boundary, а при указании --stock создаётся stock lens report. Phase 6I позволяет opt in с помощью --include-semantic-summary; Phase 6K позволяет opt in с помощью --include-stock-lens-synthesis, размещая stock lens synthesis после stock lens report. Phase 6N позволяет opt in с помощью --include-external-data-verification, размещая fixture verification после external boundary и перед stock lens report; этот шаг поддерживает только --external-data-provider fixture, читает только локальные fixture, не запрашивает live market API и не читает API key. Dry-run перечисляет только план semantic / synthesis / fixture и required acknowledgement; в confirmed execution только LLM-шаги должны предоставлять точный --api-cost-ack. Stock lens synthesis требует --stock и по умолчанию использует только 6F stock lens JSON; Phase 6V позволяет opt in reviewed semantic context с помощью --include-semantic-context / --include-semantic-context-in-synthesis, по-прежнему не читая raw transcript и не запрашивая внешние рыночные данные. Этот workflow не выполняет автоматический rebuild cache, не добавляет MCP tools и не предоставляет инвестиционных рекомендаций.

Пересоздание SQLite metadata cache и поиск:

python scripts/rebuild_cache.py --podcast gooaye --force
python scripts/search_transcripts.py --podcast gooaye --query 台積電 --limit 10 --search-mode auto
python scripts/search_transcripts.py --podcast gooaye --query 台積電 --limit 10 --search-mode like --context-segments 1
python scripts/search_mentions.py --podcast gooaye --query 台積電
python scripts/search_mentions.py --podcast gooaye --query 台積電 --type company

SQLite cache — это производные данные, которые можно удалить и пересоздать. Первоначальный source of truth по-прежнему находится в data/transcripts/, data/summaries/ и data/mentions/. Phase 3B поддерживает опциональный SQLite FTS5; если локальный SQLite не поддерживает FTS5 или query является точной подстрокой на китайском, search_transcripts() использует LIKE fallback. Результаты поиска содержат highlighted_text, фактический search_mode, а с помощью --context-segments можно получить контекст вокруг найденных фрагментов. На этом этапе по-прежнему не выполняются embedding, vector search или LLM search.

Запуск локального MCP server:

python scripts/rebuild_cache.py --podcast gooaye --force
python scripts/search_transcripts.py --podcast gooaye --query 台積電 --limit 5 --search-mode auto
python scripts/run_mcp_server.py

MCP server использует единый FastMCP instance из официального Python MCP SDK. Локальные Codex / Claude client продолжают использовать stdio; одобренный Spec 026 Hermes sidecar предоставляет через тот же registry Streamable HTTP, привязанный только к 127.0.0.1:8767/mcp, без legacy SSE и без публикации порта. Read/query tools:

  • list_episodes

  • get_episode

  • validate_transcript

  • search_transcripts

  • search_mentions

  • rebuild_cache

  • query_verified_research_report_catalog(Tool 17; автономный read-only list/search/inspect на основе манифеста)

  • revalidate_verified_research_report_sources(Tool 18; автономная повторная проверка источников по точному локатору)

  • query_verified_research_report_coverage(Tool 19; автономное объединение покрытия с фокусом на эпизод)

  • suggest_historical_verified_report_next_step(Tool 20; предложение следующего шага по историческим данным)

  • list_verified_report_gap_backlog(Tool 21; инвентаризация бэклога пробелов)

  • generate_stock_lens_report(Tool 22; детерминированный stock lens report, side-effect, dry-run-first)

  • ingest_x_video(Tool 23; ingest видео из X, preview без записи, но с чтением публичных metadata)

  • ingest_youtube_video(Tool 24; ingest видео из YouTube, preview без записи, но с чтением публичных metadata)

Side-effect tools:

  • download_audio

  • transcribe_episode

  • summarize_episode_extractive

  • extract_mentions

  • semantic_summarize_episode

  • run_research_workflow

  • run_corpus_episode_completion_workflow

  • run_corpus_latest_episode_deterministic_workflow

  • run_latest_episode_verified_research_report_workflow

  • run_episode_verified_research_report_workflow

  • generate_stock_lens_report

  • ingest_x_video

  • ingest_youtube_video

Локальный reviewed stdio registry содержит 24 tools. Tool 24 ingest_youtube_video — append-only; contracts/order Tools 1–23 не меняются. Tool 23 ingest_x_video по-прежнему является X ingest. Preview — zero-write, но читает публичные metadata; это не zero-network dry-run от corpus runner. Tool 22 generate_stock_lens_report по-прежнему является append-only dry-run-first stock lens. Это side-effect, dry-run-first детерминированный stock lens report, который читает только локальные mapping/boundary artifacts; без live market API, без сети, без LLM и без инвестиционных рекомендаций. Tool 21 list_verified_report_gap_backlog — append-only; contracts/order Tools 1–20 не меняются. Это read-query для inventory gap backlog. Tool 20 по-прежнему является historical next-step suggestion. Tool 19 по-прежнему является episode-centric coverage. Tool 18 по-прежнему является exact-locator offline source revalidation. Tool 17 сохраняет контракт catalog list/search/inspect. Указанные выше side-effect tools по умолчанию имеют confirm=false и возвращают только dry-run action plan; они не загружают, не транскрибируют и не записывают файлы; confirm=true используется только после подтверждения action plan. run_corpus_episode_completion_workflow сохраняет preview → human approval → one explicit action; run_corpus_latest_episode_deterministic_workflow обрабатывает только локальные детерминированные этапы latest episode и останавливается перед semantic summary. run_latest_episode_verified_research_report_workflow сначала требует preview, затем пользователь предоставляет тот же канонический expected_episode_ref и точный api_cost_ack, после чего выполняется только один confirmed вызов. run_episode_verified_research_report_workflow выполняет readiness preview с явным episode_ref (может быть историческим эпизодом); после подтверждения он только собирает/публикует эквивалентный digest bundle, без api_cost_ack и без вызова LLM. После завершения всех side-effect tools SQLite cache не пересоздаётся автоматически, и инвестиционные рекомендации не предоставляются. Например:

Call transcribe_episode with confirm=false first to review the action plan.
Call transcribe_episode again with confirm=true only if you accept the runtime and resource cost.

MCP responses используют JSON envelope: при успехе — {"ok": true, "data": ...}, при ошибке — {"ok": false, "error_type": "...", "message": "..."}. Dry-run action plan возвращает {"ok": true, "dry_run": true, "requires_confirmation": true, ...}. После завершения side-effect tools cache не пересоздаётся автоматически; чтобы обновить search metadata, вручную вызовите rebuild_cache. MCP search, mentions и summaries не являются инвестиционными рекомендациями.

semantic_summarize_episode — более строгий API-cost tool. Он передаёт текст транскрипта внешнему LLM provider, что может привести к расходам на API, поэтому помимо confirm=true необходимо предоставить точное acknowledgement:

I understand this may call an external LLM API, send transcript text outside this machine, and incur costs.

При первом вызове используйте confirm=false и проверьте dry-run action plan, preview проверки транскрипта, настройки chunk и риски. Только если вы принимаете риски внешнего API, передачи данных и расходов, выполняйте с confirm=true и точным api_cost_ack. MCP response не возвращает API key и не возвращает исходный текст транскрипта в dry-run. После успеха cache не пересоздаётся автоматически; чтобы SQLite cache узнал о новом артефакте .semantic.md, вручную выполните rebuild_cache.

Phase 6L добавляет MCP exposure для run_research_workflow. Этот consolidated workflow tool работает по принципу dry-run first: при confirm=false он только перечисляет planned reads/writes, порядок шагов (step order), external API / cost risk, предупреждение об устаревшем кэше (cache stale warning) и required acknowledgement, не записывает artifacts, не вызывает LLM, не возвращает raw transcript и не читает значение API key. При confirm=true вызывается существующий core workflow; если включены semantic summary или stock lens synthesis, всё равно необходимо предоставить exact ack / api_cost_ack. Workflow MCP tool не запрашивает external market data, не выполняет automatic cache rebuild и не добавляет рекомендаций по покупке/продаже, целевых цен или гарантий доходности.

Интеграция MCP-клиента

Локальные клиенты типа Codex / Claude используют существующий stdio transport:

python scripts/run_mcp_server.py

Hermes/OpenAB используют отдельный sidecar и тот же exact 21-tool registry:

wsl.exe -d UbuntuProd -u root bash scripts/build_hermes_sidecar.sh podcast-ingest-core-mcp:local
docker compose -f deploy/hermes/docker-compose.sidecar.yml config --quiet

Развёртывание, config/Skill plan→apply→rollback, direct-safe validator и способ переноса см. в deploy/hermes/README.md и specs/026-hermes-mcp-integration/quickstart.md. Direct transport проверен и работает; boolean-only endpoint-equality validator C6 прошёл targeted tests, POSIX synthetic checks, двух reviewers и единственный live v2 run, его статус — PASS-current, и его нельзя перезапускать. C7 по-прежнему Blocked; hooks Hermes v0.20.0 tag v2026.8.3 — это лишь не установленные и не проверенные на реальном оборудовании кандидатные возможности. Запрещается читать live config values/session dump, сохранять raw response, обновлять или включать hooks для дополнительного подтверждения. Spec 027 contract layer завершён (только offline assurance); фактическая маршрутизация Hermes runtime — BLOCKED/not_evaluated и не является runtime PASS. Spec 028 capability gate завершён и корректно завершается на BLOCKED_CAPABILITY для Hermes v0.20.0 tag v2026.8.3; никаких upgrade, Skill sync, hooks, collector, inference или runtime observation не выполнялось. C6 остаётся PASS-current и не перезапускался; фактическая маршрутизация Hermes Skill остаётся BLOCKED/not_run.

Перед подключением к MCP-клиенту типа Codex / Claude рекомендуется сначала запустить локальную проверку готовности (readiness check):

python scripts/validate_mcp_setup.py --podcast gooaye --query 台積電

Документация по настройке клиента (Client setup):

Эти документы используют только placeholder path. Не коммитьте личные .codex/config.toml, конфигурации с личными абсолютными путями, .env или API key.

Оценка использования инструментов MCP (MCP Tool-use Eval)

После подключения к MCP-клиенту типа Codex / Claude можно использовать eval prompt suite для проверки соответствия использования инструментов ожиданиям. Перед началом запустите:

python scripts/validate_mcp_setup.py --podcast gooaye --query 台積電

Создайте заполняемый Codex MCP session eval report:

python scripts/new_mcp_eval_report.py --name codex-session-001

Документация по eval:

Eval Phase 5B не требует реальных вызовов внешнего LLM API и не требует фактического выполнения загрузки, транскрипции, суммаризации или записи artifacts; основное внимание уделяется подтверждению tool selection, dry-run, acknowledgement guard, объяснению cache stale и отсутствию инвестиционных рекомендаций. Phase 5C предоставляет процесс report capture, позволяющий пользователю заполнить фактические результаты Codex MCP session обратно в evals/.

Оценка безопасности исследований (Research Safety Eval)

Phase 6H — это предварительный safety gate для LLM, который проверяет, что исследовательский слой и будущий LLM workflow не будут галлюцинировать, пропускать api_cost_ack, утекать raw transcript / API key, принимать external boundary за проверенные рыночные данные или выдавать инвестиционные рекомендации.

Документация по research eval:

Phase 6H не вызывает LLM, не читает API key, не запрашивает внешние рыночные данные, не добавляет MCP tools и не изменяет workflow Phase 6G. Phase 6I добавила optional semantic summary execution внутри research workflow. Phase 6J добавила Stock Lens LLM Synthesis, входная граница — только 6F stock lens JSON, обязателен exact api_cost_ack, no raw transcript, no external market data, no MCP tool changes. Phase 6K добавила workflow opt-in synthesis: include_stock_lens_synthesis выполняет synthesis только после подтверждения workflow и exact ack. Phase 6L добавила MCP exposure для run_research_workflow: dry-run first, confirmed execution только оборачивает core workflow, LLM steps по-прежнему требуют exact ack, и no automatic cache rebuild. Phase 6N добавила optional workflow fixture verification include_external_data_verification: поддерживается только локальный fixture provider, no live market API, no API key, no MCP tool changes, no automatic cache rebuild, и не предоставляет инвестиционных рекомендаций. Phase 6O добавила research-llm-smoke: real OpenAI-compatible smoke + Codex manual review, exact ack, no direct Codex-session backend, no live market data, no investment advice. Phase 6Q добавила конфигурацию LLM profile: --llm-profile pro4500 позволяет переиспользовать имена provider/model/base URL/env var, но не сохраняет значение API key. Phase 6R добавила локальный загрузчик секретов .env: для ручного LLM smoke можно использовать API_KEY, MODEL, BASE_URL, а CLI metadata показывает только имена env var, не показывая secret value. Phase 6T добавила research LLM smoke review report / quality gate: после confirmed smoke можно создавать deterministic review artifacts, no LLM call, no .env read, no external market data. Phase 6V добавила reviewed semantic context opt-in: stock lens synthesis по умолчанию по-прежнему только 6F stock lens JSON, и только после явного включения используется review-passed контекст .semantic.md, no raw transcript, no live market data, no MCP tool changes, no investment advice. Phase 6V.1 выровняла review gate boundary/context consistency: JSON-only artifact не может нести semantic context, reviewed semantic boundary обязана нести review-passed context.

Spec Kit / Архитектура

Phase 7A — это Architecture / Spec Kit Stabilization, ограниченная только docs/spec. Она приводит текущую исследовательскую систему Phase 6T обратно в отслеживаемую структуру spec-kit, не меняя runtime, не меняя MCP, не вызывая LLM, не читая .env, не запрашивая external market data и не ослабляя границу no investment advice. После Phase 7A следующий кандидат на функциональный этап — Phase 6U semantic summary smoke или небольшая настройка качества вывода LLM (LLM output-quality tuning).

Phase 7B — это Official Spec Kit Bootstrap. Проект официально добавил scaffold, эквивалентный specify init: .specify хранит Spec Kit memory, templates, scripts, workflow и integration metadata; .agents/skills хранит skills $speckit-* для Codex skills mode; AGENTS.md хранит repo-level agent rules. Phase 7B не меняет runtime, не меняет MCP, не вызывает LLM, не читает .env, не запрашивает live market API и не ослабляет границу no investment advice.

Phase 7C — это Spec Kit Constitution + Workflow Alignment. Этот этап превращает .specify/memory/constitution.md из официального placeholder в проектную конституцию и синхронизирует .specify/templates/, AGENTS.md, architecture, roadmap и spec plan. Phase 7C — только docs/spec/tests: no runtime behavior change, no MCP behavior change, no LLM call, no .env read, no live market API, no investment advice. После Phase 7C новые функции должны проходить полный Spec Kit flow: $speckit-constitution, $speckit-specify, $speckit-clarify, $speckit-plan, $speckit-checklist, $speckit-tasks, $speckit-analyze, $speckit-implement, $speckit-converge; $speckit-taskstoissues используется только при необходимости GitHub issue handoff. Phase 6U semantic summary smoke по-прежнему остаётся возможным последующим функциональным этапом.

Phase 7D — это Spec Kit Backfill via Full Workflow. Этот этап использует полный Spec Kit flow для capability-group backfill уже разработанных возможностей: specs/README.md — это registry, 001-gooaye-research-system остаётся umbrella product spec, 002-ingestion-transcript-core007-spec-kit-governance фиксируют as-built capability packages, где 006-llm-safety-synthesis-smoke-review покрывает optional LLM/smoke/review gate. Phase 7D — только docs/spec/tests: no runtime behavior change, no MCP behavior change, no LLM call, no .env read, no live market API, no investment advice, и явно фиксирует шаги backfill для $speckit-clarify, $speckit-analyze, $speckit-converge.

Phase 7D.1 — это Spec Kit Active Feature Guidance. Этот этап уточняет usability официальных команд Spec Kit: правильное расположение feature packages — specs/<feature>, .specify/ — это scaffold/memory/templates/scripts metadata; несколько backfilled packages по умолчанию не закрепляют один active feature. Чтобы запустить official scripts / skills для конкретного package, сначала задайте SPECIFY_FEATURE_DIRECTORY, например $env:SPECIFY_FEATURE_DIRECTORY="specs/003-metadata-search-mcp-core"; официальный script может сохраняться в .specify/feature.json, при переключении package просто задайте его заново. Phase 7D.1 не меняет runtime, не меняет MCP, не вызывает LLM, не читает .env, не запрашивает live market API и не предоставляет investment advice. Phase 6U semantic summary smoke по-прежнему остаётся возможным последующим функциональным этапом.

Документация Spec-kit:

Лицензия

Этот репозиторий лицензирован под MIT License. См. LICENSE. Это авторское право распространяется только на работы первой стороны: два spec packages включают byte-pinned snapshot стороннего репозитория NousResearch/hermes-agent, который имеет собственную лицензию MIT. См. THIRD-PARTY-NOTICES.md.

Команды разработки

python -m pytest
python -m compileall src scripts

Чтобы установить зависимости для разработки:

python -m pip install -e .[dev]

Spec034 Task #82 v8 review repair — текущий

startup/plugin закрыт; credential_provider BLOCKED; в целом BLOCKED. Spec034 остаётся offline/static-only, с H2 ровно 20 upstream paths при H1 SHA-256 90ba45ccf11bbcbf446f7d16904964073e84837a04aaaa0c6f4887d3ea75109d; никакой 21-й path не авторизован. Изолированный child принимает только обычный no-link/reparse-free project snapshot в качестве payload cwd, изменяет его до импорта sentinel/Pytest/product и сохраняет только capability snapshot, затем project snapshot, затем stdlib. Следовательно, три относительных чтения конфигурации C6 используют snapshot-approved bytes, даже если исходные конфигурации рабочей области изменятся после создания snapshot. Публичная проекция receipt не имеет внедрённого verifier; приватная выдача пересчитывает текущие canonical facts. AST proof следует одному owner-local flow package spec/module/loader/return/register/context. Bundle rename parent fsync предшествует журналу bundle_renamed с явным platform best-effort fallback, и только точное nonce-bound восстановление both-missing является retry-safe. Тесты runner/journal/trust остаются нефинальными. Каждый предыдущий root не является доказательством одобрения. Требуются свежие повторные ревью кода и архитектуры; только Main может запустить документированную one-shot command после обоих PASS, и здесь она не запускалась.

A
license - permissive license
Not graded
quality - not tested
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

  • F
    license
    Not graded
    quality
    D
    maintenance
    A dual-transport MCP server that exposes your API as tools to LLM clients, supporting both stdio transport for local clients like Claude Desktop and HTTP/SSE transport for remote clients like OpenAI's Responses API.

View all related MCP servers

Related MCP Connectors

  • Podcast Index MCP — wraps the Podcast Index API (podcastindex.org)

  • Turn a GitHub repo or docs site into agent-ready context: pack it or search it, over MCP.

  • MCP server for Clipkit — gives AI agents a video toolbox via the Clipkit schema.

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/norton77930/corpus-ingest-core'

If you have feedback or need assistance with the MCP directory API, please join our Discord server