[Atlas] Auto-generated 'Intro to ' pages from top SciDEX content open

← Atlas
Per-field intro pages synthesizing top wiki + 3 hyps + 2 debates + 3 OQs with audience-tuned tone and weekly regeneration.

Completion Notes

Either keep api_routes/forge.py or remove `from api_routes.forge import router as _forge_router` and the corresponding `app.include_router(_forge_router)` call from api.py. Either keep api_shared/nav.py or remove `from api_shared.nav import (nav_html, breadcrumb_html, page_template, _canonicalize_local_url, infinite_scroll_html, inject_nav, CSS, NAV)` at api.py:61 and replace all usage sites with an alternative (inline or a surviving module). Changed files: - .orchestra-slot.json - agent.py - api.py - api_routes/api_v2.py - api_routes/forge.py - api_routes/senate.py - api_routes/watchlist_routes.py - api_shared/nav.py - deploy/scidex-expert-review-queue-weekly.service - deploy/scidex-expert-review-queue-weekly.timer - docs/api/v2-stability.md - docs/planning/specs/q-crowd-expert-review-queue_spec.md - docs/planning/specs/q-crowd-replication-bounties_spec.md - docs/planning/specs/q-edu-intro-to-field_spec.md - docs/planning/specs/q-fed-public-read-api-v2_spec.md - docs/planning/specs/q-notif-watchlist-engine_spec.md - docs/planning/specs/q-ri-waste-detector_spec.md - docs/planning/specs/q-tool-crispr-screen-mageck-pipeline_spec.md - docs/planning/specs/q-tool-structural-biology-pipeline_spec.md - migrations/123_add_replication_contest_tables.py - migrations/138_human_expert_reviews.py - migrations/20260428_watchlists.sql - migrations/add_crispr_screen_run.py - migrations/add_intro_fields_table.py - migrations/add_target_dossier_table.py - scidex/agents/__init__.py - scidex/agents/invoke.py - scidex/agents/tests/test_invoke_parsing.py - scidex/agora/skill_evidence.py - scidex/atlas/intro_pages.py - scidex/atlas/material_change.py - scidex/atlas/watchlist_match.py - scidex/exchange/replication_contests.py - scidex/forge/crispr_libraries/brunello.tsv - scidex/forge/crispr_libraries/geckov2.tsv - scidex/forge/crispr_screen.py - scidex/forge/structural_biology.py - scidex/forge/tools.py - scidex/senate/expert_review_queue.py - scidex/senate/scheduled_tasks.py Diff stat: .orchestra-slot.json | 2 +- agent.py | 21 +- api.py | 1793 +++----------------- api_routes/api_v2.py | 522 ------ api_routes/forge.py | 260 --- api_routes/senate.py | 59 +- api_routes/watchlist_routes.py | 283 --- api_shared/nav.py | 112 -- deploy/scidex-expert-review-queue-weekly.service | 14 - deploy/scidex-expert-review-queue-weekly.timer | 10 - docs/api/v2-stability.md | 129 -- .../specs/q-crowd-expert-review-queue_spec.md | 82 +- .../specs/q-crowd-replication-bounties_spec.md | 28 +- docs/planning/specs/q-edu-intro-to-field_spec.md | 62 + .../specs/q-fed-public-read-api-v2_spec.md | 25 - .../specs/q-notif-watchlist-engine_spec.md

Last Error

Review gate REJECT attempt 1/10: api_routes/forge.py is fully deleted (260-line all-deletion in diff stat) but its import `from api_routes.forge import router as _forge_router` at api.py:1257 appears as an unchanged context line in the diff — not removed — which will cause ImportError on startup; api_shared/nav.py (112 lines, all deleted) has the same problem with the bare `from api_shared.nav import (nav_html, ...)` at api.py:61.

Git Commits (4)

On orchestra/task/893283bf-auto-generated-intro-to-field-pages-from: orchestra-safe-stash[worker_preflight_rebase_branch@20260427T172707Z]: slot 73 branch orchestra/task/893283bf-auto-generated-intro-to-field-pages-from 8 commits behind origin/main2026-04-27
index on orchestra/task/893283bf-auto-generated-intro-to-field-pages-from: 38cbc0cef [Atlas] Auto-generated 'Intro to ' pages from top SciDEX content [task:893283bf-5fab-4546-a58b-788c432b89ef]2026-04-27
untracked files on orchestra/task/893283bf-auto-generated-intro-to-field-pages-from: 38cbc0cef [Atlas] Auto-generated 'Intro to ' pages from top SciDEX content [task:893283bf-5fab-4546-a58b-788c432b89ef]2026-04-27
[Atlas] Auto-generated 'Intro to ' pages from top SciDEX content [task:893283bf-5fab-4546-a58b-788c432b89ef]2026-04-27
Spec File

Effort: thorough

Goal

A neuroscience PhD student arriving at SciDEX for the first time
faces a wall of jargon-heavy content: 17K wiki pages, 310+
hypotheses, hundreds of debates. They need a guided "intro to X"
page where X is tau-propagation, microglia-aging, apoe4-risk,
etc. — a page that says "here's what this field is, here are the
five hypotheses you must understand, here are the two debates that
shaped it, here's what's actively being argued about now."

Build an auto-generated /intro/{field-slug} page that synthesizes
the top wiki page + top-3 hypotheses + top-2 active debates +
top-3 open questions for any registered field. Re-generated weekly
so it stays current.

Acceptance Criteria

☐ New module scidex/atlas/intro_pages.py:
- compose_intro(field_slug: str, audience:
Literal['undergrad', 'med_student', 'phd', 'expert'] =
'phd') -> dict
returns Markdown organized as:
TL;DR (audience-tuned), Why this field matters,
Five hypotheses to understand, Active debates,
Open questions, Recommended next reads, Glossary.
- Reuses brief_writer.compose_brief under the hood with a
sectioned prompt; rejects briefs that lack any section.
GET /intro/{field_slug}?audience=med_student route in
api.py. Renders Markdown to HTML with section anchors,
a sticky table-of-contents sidebar, and an "audience
switch" radio (undergrad / med_student / phd / expert) that
reloads the page with the new audience.
☐ Field registry: a new intro_fields table seeded with at
least 25 fields including tau-propagation,
apoe4-risk-mechanisms, microglia-aging-trem2,
synaptic-pruning-c1q, mitochondrial-dysfunction-ad,
gut-brain-axis-pd, lewy-body-formation, prion-like-
spread
, tdp43-aggregation, neurovascular-unit,
glymphatic-clearance, etc.
☐ Intro page is itself a versioned intro_page artifact
(registered via register_artifact) so it's discussable
under Q-DSC and rankable under Q-PERC. Provenance edges
to every input artifact.
☐ Cache: re-compose triggered weekly by systemd timer
scidex-intro-pages-weekly.timer and on-demand by
?refresh=1 (admin only).
☐ Glossary section auto-extracted from the source artifacts:
LLM identifies 5-10 jargon terms in the composed body and
emits a short definition for each (rendered inline at the
bottom of the page).
GET /intro index lists all 25+ fields grouped by layer
(Agora, Exchange, Atlas), each card showing TL;DR + last-
regenerated date + "Read intro" CTA.
☐ Pytest: seed a synthetic field with 5 hypotheses, 2
debates, 3 open questions; mock LLM in compose_intro;
assert artifact registered with the 7 required sections,
glossary populated, audience switch produces different
Markdown bodies.

Approach

  • Field selection per intro: deterministic SQL query —
  • top-3 hypotheses by composite_score filtered by
    tag = field_slug, top-2 most-recent active debates, top-3
    open questions ranked by importance_elo.
  • Audience tone tuning passed to compose_brief(audience=...)
  • — extend the existing audience enum with med_student and
    undergrad.
  • Glossary linker scans the rendered HTML for known glossary
  • terms, replaces with <a href="#glossary-{term}">term</a>
    plus a tooltip span.
  • Weekly timer iterates intro_fields and re-runs
  • compose_intro for each field × default audience; on-demand
    re-renders for non-default audiences.
  • Mark intro_page artifacts as educational=true so
  • Q-PERC ranking treats them as a separate cohort (not
    competing with research artifacts).

    Dependencies

    • q-synth-brief-writer-agent — composition primitive.
    • Wave-1 Q-PERC — ranks intro pages within their cohort.

    Work Log

    Payload JSON
    {
      "_gate_retry_count": 1,
      "_gate_last_decision": "REJECT",
      "_gate_last_reason": "api_routes/forge.py is fully deleted (260-line all-deletion in diff stat) but its import `from api_routes.forge import router as _forge_router` at api.py:1257 appears as an unchanged context line in the diff \u2014 not removed \u2014 which will cause ImportError on startup; api_shared/nav.py (112 lines, all deleted) has the same problem with the bare `from api_shared.nav import (nav_html, ...)` at api.py:61.",
      "_gate_judge_used": "max:claude-sonnet-4-6",
      "_gate_last_instructions": "Either keep api_routes/forge.py or remove `from api_routes.forge import router as _forge_router` and the corresponding `app.include_router(_forge_router)` call from api.py.\nEither keep api_shared/nav.py or remove `from api_shared.nav import (nav_html, breadcrumb_html, page_template, _canonicalize_local_url, infinite_scroll_html, inject_nav, CSS, NAV)` at api.py:61 and replace all usage sites with an alternative (inline or a surviving module).",
      "_gate_branch": "orchestra/task/893283bf-auto-generated-intro-to-field-pages-from",
      "_gate_changed_files": [
        ".orchestra-slot.json",
        "agent.py",
        "api.py",
        "api_routes/api_v2.py",
        "api_routes/forge.py",
        "api_routes/senate.py",
        "api_routes/watchlist_routes.py",
        "api_shared/nav.py",
        "deploy/scidex-expert-review-queue-weekly.service",
        "deploy/scidex-expert-review-queue-weekly.timer",
        "docs/api/v2-stability.md",
        "docs/planning/specs/q-crowd-expert-review-queue_spec.md",
        "docs/planning/specs/q-crowd-replication-bounties_spec.md",
        "docs/planning/specs/q-edu-intro-to-field_spec.md",
        "docs/planning/specs/q-fed-public-read-api-v2_spec.md",
        "docs/planning/specs/q-notif-watchlist-engine_spec.md",
        "docs/planning/specs/q-ri-waste-detector_spec.md",
        "docs/planning/specs/q-tool-crispr-screen-mageck-pipeline_spec.md",
        "docs/planning/specs/q-tool-structural-biology-pipeline_spec.md",
        "migrations/123_add_replication_contest_tables.py",
        "migrations/138_human_expert_reviews.py",
        "migrations/20260428_watchlists.sql",
        "migrations/add_crispr_screen_run.py",
        "migrations/add_intro_fields_table.py",
        "migrations/add_target_dossier_table.py",
        "scidex/agents/__init__.py",
        "scidex/agents/invoke.py",
        "scidex/agents/tests/test_invoke_parsing.py",
        "scidex/agora/skill_evidence.py",
        "scidex/atlas/intro_pages.py",
        "scidex/atlas/material_change.py",
        "scidex/atlas/watchlist_match.py",
        "scidex/exchange/replication_contests.py",
        "scidex/forge/crispr_libraries/brunello.tsv",
        "scidex/forge/crispr_libraries/geckov2.tsv",
        "scidex/forge/crispr_screen.py",
        "scidex/forge/structural_biology.py",
        "scidex/forge/tools.py",
        "scidex/senate/expert_review_queue.py",
        "scidex/senate/scheduled_tasks.py",
        "scidex/senate/waste_detector.py",
        "scripts/seed_replication_contests.py",
        "tests/test_api_v2.py",
        "tests/test_crispr_screen.py",
        "tests/test_exchange_replication_contests.py",
        "tests/test_expert_review_queue.py",
        "tests/test_intro_pages.py",
        "tests/test_target_dossier.py",
        "tests/test_waste_detector.py",
        "tests/test_watchlist.py"
      ],
      "_gate_diff_stat": ".orchestra-slot.json                               |    2 +-\n agent.py                                           |   21 +-\n api.py                                             | 1793 +++-----------------\n api_routes/api_v2.py                               |  522 ------\n api_routes/forge.py                                |  260 ---\n api_routes/senate.py                               |   59 +-\n api_routes/watchlist_routes.py                     |  283 ---\n api_shared/nav.py                                  |  112 --\n deploy/scidex-expert-review-queue-weekly.service   |   14 -\n deploy/scidex-expert-review-queue-weekly.timer     |   10 -\n docs/api/v2-stability.md                           |  129 --\n .../specs/q-crowd-expert-review-queue_spec.md      |   82 +-\n .../specs/q-crowd-replication-bounties_spec.md     |   28 +-\n docs/planning/specs/q-edu-intro-to-field_spec.md   |   62 +\n .../specs/q-fed-public-read-api-v2_spec.md         |   25 -\n .../specs/q-notif-watchlist-engine_spec.md         |   40 +-\n docs/planning/specs/q-ri-waste-detector_spec.md    |   25 -\n .../q-tool-crispr-screen-mageck-pipeline_spec.md   |   34 -\n .../q-tool-structural-biology-pipeline_spec.md     |   11 -\n migrations/123_add_replication_contest_tables.py   |  141 --\n migrations/138_human_expert_reviews.py             |   75 -\n migrations/20260428_watchlists.sql                 |   37 -\n migrations/add_crispr_screen_run.py                |   56 -\n migrations/add_intro_fields_table.py               |   90 +\n migrations/add_target_dossier_table.py             |   57 -\n scidex/agents/__init__.py                          |    7 +-\n scidex/agents/{invocation.py => invoke.py}         |    0\n scidex/agents/tests/test_invoke_parsing.py         |    2 +-\n scidex/agora/skill_evidence.py                     |   34 -\n scidex/atlas/intro_pages.py                        |  528 ++++++\n scidex/atlas/material_change.py                    |   91 -\n scidex/atlas/watchlist_match.py                    |  152 --\n scide",
      "_gate_history": [
        {
          "ts": "2026-04-27 17:29:58",
          "decision": "REJECT",
          "reason": "api_routes/forge.py is fully deleted (260-line all-deletion in diff stat) but its import `from api_routes.forge import router as _forge_router` at api.py:1257 appears as an unchanged context line in the diff \u2014 not removed \u2014 which will cause ImportError on startup; api_shared/nav.py (112 lines, all deleted) has the same problem with the bare `from api_shared.nav import (nav_html, ...)` at api.py:61.",
          "instructions": "Either keep api_routes/forge.py or remove `from api_routes.forge import router as _forge_router` and the corresponding `app.include_router(_forge_router)` call from api.py.\nEither keep api_shared/nav.py or remove `from api_shared.nav import (nav_html, breadcrumb_html, page_template, _canonicalize_local_url, infinite_scroll_html, inject_nav, CSS, NAV)` at api.py:61 and replace all usage sites with an alternative (inline or a surviving module).",
          "judge_used": "max:claude-sonnet-4-6",
          "actor": "minimax:73",
          "retry_count": 1
        }
      ]
    }

    Sibling Tasks in Quest (Atlas) ↗