> ## Continuous-process anchor
>
> This spec describes an instance of one of the retired-script themes
> documented in docs/design/retired_scripts_patterns.md. Before
> implementing, read:
>
> 1. The "Design principles for continuous processes" section of that
> atlas — every principle is load-bearing. In particular:
> - LLMs for semantic judgment; rules for syntactic validation.
> - Gap-predicate driven, not calendar-driven.
> - Idempotent + version-stamped + observable.
> - No hardcoded entity lists, keyword lists, or canonical-name tables.
> - Three surfaces: FastAPI + orchestra + MCP.
> - Progressive improvement via outcome-feedback loop.
> 2. The theme entry in the atlas matching this task's capability:
> S7 (pick the closest from Atlas A1–A7, Agora AG1–AG5,
> Exchange EX1–EX4, Forge F1–F2, Senate S1–S8, Cross-cutting X1–X2).
> 3. If the theme is not yet rebuilt as a continuous process, follow
> docs/planning/specs/rebuild_theme_template_spec.md to scaffold it
> BEFORE doing the per-instance work.
>
> **Specific scripts named below in this spec are retired and must not
> be rebuilt as one-offs.** Implement (or extend) the corresponding
> continuous process instead.
Keep the task queue populated with substantive, high-value one-shot work
derived from active quests. When the queue runs low, an LLM agent
inspects each active quest, understands its intent, audits the current
DB and codebase state for gaps against that intent, and creates targeted
new tasks for the agent fleet to pick up.
On 2026-04-13 the task queue had drained to 0 one-shot tasks (only 88
recurring drivers running, mostly no-ops). All substantive feature work
in the prior 12 hours came from interactive user sessions, not Orchestra.
Reason: nothing was generating new tasks from quests.
The original scripts/quest_engine.py is a hardcoded template generator
— it has Python functions per quest with hardcoded SQL queries and task
title strings. Adding a new quest requires writing new Python code. It
also can't adapt to new opportunities the original author didn't predict.
This task replaces that with an LLM-driven generator that reads quest
intent and DB state to generate appropriate work.
SELECT COUNT(*) FROM tasks
WHERE project_id IN (SELECT id FROM projects WHERE name='SciDEX')
AND status IN ('open','available') AND task_type != 'recurring' - If >= 50: exit cleanly (no-op, queue is healthy, nothing to do)
- If < 50: continue
SELECT id, name, description, layer, priority FROM quests
WHERE project_id IN (SELECT id FROM projects WHERE name='SciDEX')
AND status = 'active' ORDER BY priority DESCdocs/planning/specs/ if one existsorchestra create:orchestra create \
--title "[Layer] Specific actionable title" \
--project SciDEX \
--quest "<Quest Name>" \
--priority <90-95> \
--description "<concrete steps + how to verify>" \
--spec docs/planning/specs/<spec_file>.mdSave these for the agent to reference:
Open one-shot count:
SELECT COUNT(*) FROM tasks
WHERE project_id = (SELECT id FROM projects WHERE name='SciDEX')
AND status IN ('open','available') AND task_type != 'recurring';Active quests with current open task counts:
SELECT q.name, q.priority, q.description,
(SELECT COUNT(*) FROM tasks t
WHERE t.quest_id = q.id
AND t.status IN ('open','available','running')) as open_count
FROM quests q
WHERE q.project_id = (SELECT id FROM projects WHERE name='SciDEX')
AND q.status = 'active'
ORDER BY q.priority DESC;Recent commits per layer (last 24h):
git log --since="24 hours ago" --format="%s" | grep -oE '^\[[A-Za-z]+\]' | sort | uniq -cVerification:
git diff origin/main..HEAD --stat shows only intended changes: quest_engine.py (writable=False fix) + spec work logpython3 -m py_compile quest_engine.py passedpython3 quest_engine.py --dry-run shows queue depth 50 (healthy, at threshold)Status: DONE — queue is healthy at 50, no action needed this cycle.
Initial verification:
git diff origin/main..HEAD --stat was empty; only .orchestra-slot.json was locally modified by the slot launcher.scidex status showed the API, nginx, linkcheck, and Neo4j active; PostgreSQL had 396 analyses, 846 hypotheses, 711973 KG edges, and 3089 open gaps./home/ubuntu/Orchestra/orchestra.db showed the SciDEX open one-shot queue depth was 2.python3 quest_engine.py --dry-run failed before reading queue depth because the engine required a write probe against the authoritative Orchestra DB even for read-only dry-run verification.--dry-run.python3 -m py_compile quest_engine.py and python3 quest_engine.py --dry-run.open_readonly_sqlite() and changed get_orchestra_db() to accept writable=True by default.run(dry_run=True) now opens the authoritative Orchestra DB in SQLite mode=ro, skips write probes/schema mutation, and still refuses fallback if the authoritative DB is present but unreadable.writable=True, so a present but non-writable authoritative DB remains a hard failure instead of falling through to stale fallback state.python3 -m py_compile quest_engine.py passed.python3 quest_engine.py --dry-run read authoritative queue depth 2 and found 10 non-duplicate candidate tasks.python3 quest_engine.py still failed in this sandbox with the expected authoritative-DB write-access error; task creation must run where the supervisor has write access to the authoritative Orchestra DB.Initial verification:
git diff origin/main..HEAD --stat was empty; only .orchestra-slot.json was locally modified by the slot launcher./data/orchestra/orchestra.db had 2 open SciDEX one-shot tasks, while stale fallback /tmp/orchestra_data/orchestra.db had 50.python3 quest_engine.py --dry-run incorrectly exited no-op because the sandbox could not write the authoritative DB and the engine fell through to the stale fallback.quest_engine.py so a present authoritative Orchestra DB that is readable but not writable is a hard failure instead of falling through to fallback paths.python3 -m py_compile quest_engine.py passed.Initial verification:
git diff origin/main..HEAD --stat showed the prior engine/spec expansion already on main except the seven new reusable specs.python3 -m py_compile quest_engine.py passed.python3 quest_engine.py --dry-run saw queue depth 44 and all existing Cycle 20/21 candidates were duplicate-blocked.python3 quest_engine.py --dry-run then reported 6 non-duplicate candidates and preserved duplicate blocks for existing candidates.python3 quest_engine.py; created 6 new quest-tagged tasks:
6a311d99-ff65-4e0d-a21a-d89a305f5695 - [Agora] Add counter-evidence reviews to 10 hypotheses missing evidence_against62d50302-1202-44bd-865a-990bc490e038 - [Agora] Generate falsifiable predictions for 25 hypotheses with none84798e7f-294c-471f-a240-4bdc6c60bba3 - [Atlas] Add pathway diagrams to 20 hypotheses missing mechanism mapsd028e4a0-e04f-44a7-b285-8f710493d203 - [Exchange] Add clinical-trial context to 20 hypotheses missing trial signals8b952ef4-a91d-4dc2-bee8-67422efdbeda - [Atlas] Link 50 evidence entries to target artifactsba45d928-2a31-494a-a249-99edeaeee484 - [Senate] Link 50 isolated artifacts into the governance graphPost-check:
python3 quest_engine.py --dry-run exited cleanly with queue is healthy (50 >= 50); no action.python3 -m py_compile quest_engine.py passed.Initial verification:
git fetch origin/main && git rebase origin/main completed successfully.python3 -m py_compile quest_engine.py passed.python3 quest_engine.py --dry-run saw queue depth 36 and identified 8 non-duplicate candidates.00ec851f-b418-4502-9dba-357da4eee22e — [Senate] Review 25 open Senate proposals for decision readinessf7ad4ead-31ea-4d82-b2dc-e3b59a8f551d — [Agora] Run target debates for 25 undebated therapeutic targets5690901e-9d3c-4f9f-9bd4-f2e47a40f85a — [Exchange] Audit 50 open unclaimed token bounties for claimability9d486708-83c0-4987-804b-98e04d106767 — [Forge] Triage 50 failed tool calls by skill and error modebf9c6e36-b3f2-4c61-9039-8a869011a493 — [Forge] Score performance for 25 unscored registered skills4ff74a2a-53da-4b30-909b-a30166470c92 — [Senate] Distribute discovery dividends for 3 pending world-model improvements9ae12354-35f8-436d-85b8-5a4f5a6dc2c2 — [Senate] Capture belief snapshots for 50 hypotheses missing recent state967c5cb5-616a-4d21-8780-42cf99198e49 — [Atlas] Remediate 3 wiki pages with low Wikipedia parity scoresStatus: DONE — 8 tasks created, queue replenished. Exit cleanly.
Initial verification:
git diff origin/main..HEAD --stat showed the prior Cycle 20 expansion commit already merged at HEAD.python3 -m py_compile quest_engine.py passed.python3 quest_engine.py --dry-run saw queue depth 44 and would create 6 additional non-duplicate tasks.Fix implemented:
python3 quest_engine.py and python3 quest_engine.py --dry-run immediately afterward exited cleanly because the queue was healthy at 50.6a311d99-ff65-4e0d-a21a-d89a305f5695 - [Agora] Add counter-evidence reviews to 10 hypotheses missing evidence_against62d50302-1202-44bd-865a-990bc490e038 - [Agora] Generate falsifiable predictions for 25 hypotheses with none84798e7f-294c-471f-a240-4bdc6c60bba3 - [Atlas] Add pathway diagrams to 20 hypotheses missing mechanism mapsd028e4a0-e04f-44a7-b285-8f710493d203 - [Exchange] Add clinical-trial context to 20 hypotheses missing trial signals8b952ef4-a91d-4dc2-bee8-67422efdbeda - [Atlas] Link 50 evidence entries to target artifactsba45d928-2a31-494a-a249-99edeaeee484 - [Senate] Link 50 isolated artifacts into the governance graphStatus: DONE - queue replenished to 50 and the engine has broader non-duplicate gap coverage for future low-queue cycles.
Merge-gate retry check:
git diff origin/main..HEAD --stat was empty at HEAD; the substantive quest-engine repair existed only in the working tree from the blocked attempt.SPEC_PATHS resolves to an existing spec file. Missing reusable specs were added for governance triage, content ownership, quality-gate triage, market proposal review, zero-volume markets, stale market resolution, paper claim extraction, and wiki reference backfill.python3 -m py_compile quest_engine.py passed.python3 quest_engine.py --dry-run saw queue depth 36 and created 0 tasks because all 24 current candidates were exact-title or fuzzy duplicates.Initial verification:
git diff origin/main..HEAD --stat was clean except the local slot reservation file before edits.python3 -m py_compile quest_engine.py passed.python3 quest_engine.py saw queue depth 30 but created 0 tasks because all existing candidates were exact-title or fuzzy duplicates.Fix implemented:
--dry-run reports exact/fuzzy duplicate blocks instead of overstating would-create counts.python3 quest_engine.py; created 6 new quest-tagged tasks:
0813e75b-6817-441e-a1c0-57bd0a0d0248 - [Exchange] Calibrate liquidity bands for 25 low-liquidity active markets8248b3bd-4602-46b7-a9cc-f5c7f4550715 - [Senate] Audit 25 uncredited agent contributions for reward emissiond58f5f20-bcb6-449a-9025-8633897d439b - [Agora] Calibrate confidence scores for 20 active zero-confidence hypotheses978edcd3-f41c-4b47-9fca-042fe408752a - [Forge] Cache full text for 30 cited papers missing local fulltext1eba8754-8226-48b3-b44e-56716b887ba3 - [Atlas] Extract figures from 30 papers missing figure metadatabe9102e7-24aa-42d3-8884-db5e650ca67a - [Atlas] Link 25 wiki pages missing KG node mappingsPost-check:
python3 quest_engine.py --dry-run created 0 tasks and reported all 16 current candidates as duplicate-blocked.Initial verification:
git diff origin/main..HEAD --stat was empty; the prior read-only DB fix was already on main.python3 -m py_compile quest_engine.py passed before edits.python3 quest_engine.py --dry-run saw queue depth below threshold and only a narrow candidate set.python3 quest_engine.py created/observed exact-title duplicates for the existing candidate set, leaving the queue low.Fix implemented:
python3 quest_engine.py created 6 Senate/Exchange tasks and a follow-up run created 2 Forge/Atlas provenance tasks.python3 -m py_compile quest_engine.py passed.Initial verification:
git diff origin/main..HEAD --stat clean (prior work already merged).python3 -m py_compile quest_engine.py passed.python3 quest_engine.py --dry-run found 6 candidates with queue depth 16.39cb94c7-dc2f-455b-aa8f-30e4586ac589 — [Agora] Run debates for 10 analyses without debate sessions2c145957-5beb-4ff3-a843-5eaa8d729b05 — [Agora] Add data-support scores to 20 active hypotheses16587999-2b10-4855-ae47-29837b238fcf — [Atlas] Score 30 open knowledge gaps with quality rubric0239e081-9b78-4643-8de0-ed42ccaf8fb2 — [Atlas] Add resolution criteria to 25 open knowledge gaps0c9380bc-e087-4564-b68f-1018736c60c2 — [Forge] Render 25 notebooks missing HTML outputsdb4df339-b700-47a1-b17e-1db243188805 — [Atlas] Score 8 registered datasets for quality and provenanceDuplicates blocked:
[Forge] Add PubMed abstracts to 30 papers missing them → exact_title match[Atlas] Add mermaid diagrams to 10 wiki entity pages → exact_title matchInitial verification:
git diff origin/main..HEAD --stat was empty; the prior read-only DB fix is already on main.python3 -m py_compile quest_engine.py passed.python3 quest_engine.py --dry-run saw queue depth 16 and only three existing candidates.python3 quest_engine.py exited 0 but created 0 tasks because all three candidates were exact-title duplicates already open.Planned fix:
Initial verification:
python3 -m py_compile quest_engine.py passed.python3 quest_engine.py --dry-run found 3 concrete candidates with queue depth 2.python3 quest_engine.py failed before creating new tasks: sqlite3.OperationalError: attempt to write a readonly database./home/ubuntu/Orchestra/orchestra.db now resolves to /data/orchestra/orchestra.db, which exists and is readable but is not writable from this worker sandbox. The engine accepted the readable database and only discovered the problem during task insertion, so it never reached the writable /tmp/orchestra_data/orchestra.db fallback.Fix implemented:
quest_engine.py now performs a transactional SQLite write probe before accepting an Orchestra DB path.python3 -m py_compile quest_engine.py passed after the fix.python3 quest_engine.py skipped the read-only primary DB, used /tmp/orchestra_data/orchestra.db, saw queue depth 16, and exited 0.c031203d-3e22-4ecf-a674-ba5f637e81bb - [Forge] Add PubMed abstracts to 30 papers missing themb17a40df-4d42-4cf3-8ddf-52fe7df82528 - [Atlas] Add mermaid diagrams to 10 wiki entity pages5d50e873-b636-46d2-b056-594ac7ea7a22 - [Atlas] Expand 10 wiki stubs with cited neurodegeneration contextStatus: DONE - fixed the read-only DB crash; no duplicate tasks created.
Discovered queue had 0 one-shot tasks. Root cause: no CI task was
running quest_engine.py (and the existing engine is hardcoded templates).
Registered recurring task 80ffb77b at every-30-min frequency in
agent execution mode (LLM-driven, not script).
Manual run of legacy quest_engine.py created 5 tasks as a stop-gap.
This LLM-driven version replaces it.
Queue state: 1377 open one-shot tasks (healthy: True, threshold=50)
Queue state: 1389 open one-shot tasks (healthy: True, threshold=50)
scripts/quest_engine_helpers.py exists and is functional:
get_queue_depth() → 1389 open one-shot, project_id=5e530ff5get_active_quests_state() → Exchange at 101 open (near cap), Agora at 45get_top_gaps() → returns gap list sorted by priorityget_scidex_state() → full state snapshot/tmp/orchestra_copy.db when live DB lockedQueue state: 606 open one-shot tasks (healthy: True, threshold=50)
get_top_gaps() crashed with sqlite3.DatabaseError: database disk image is malformed when querying corrupted FTS/B-tree tables. Fixed by wrapping gap queries in try/except blocks — now degrades gracefully with db_corruption_partial sentinel gap instead of crashing. Committed fix.Changes committed:
scripts/quest_engine_helpers.py: Wrap get_top_gaps() gap queries in try/except for corruption resilience. Initial analyses/debates queries return db_corruption sentinel (priority 99) on failure. Subsequent queries return db_corruption_partial (priority 50) so partial results still surface.Queue state: 3 open one-shot tasks (healthy: False, threshold=50)
[UI] Fix hypothesis page 22s hang, [UI] Fix 500 errors on /atlas and /notebooks, [Demo] SEA-AD Single-Cell Analysis[Agora] Score 18 unscored hypotheses with composite scoring (id: fcda018c) — quest c488a683-47f[Agora] Add PubMed evidence to 20 hypotheses lacking citations (id: b79feec1) — quest c488a683-47f[Atlas] Score 50 unscored artifacts with quality scoring (id: 6830d8b4) — quest 415b277f-03b[Atlas] Expand 10 wiki stubs to 400+ words with literature (id: e0f8f053) — quest 1baa2fb6-21fChanges committed: Updated this spec work log.
Queue state: 13 open/available + 1 running = 14 active SciDEX tasks (healthy: False, threshold=50)
[Atlas] Add mermaid pathway diagrams to 10 wiki entity pages (id: 5a373c40) — quest 415b277f-03b — P80 gap: 48 entities lacking diagrams[Atlas] Score 30 paper artifacts with quality scoring (id: ebade91a) — quest 415b277f-03b — P85 gap: 167 unscored artifacts[Forge] Add PubMed abstracts to 30 papers missing them (id: f13984eb) — quest dd0487d3-38a — P82 gap: 228 papers lacking abstractsDuplicates blocked (already have open tasks):
Queue state: 21 open SciDEX tasks (healthy: False, threshold=50)
[Agora] Add PubMed evidence to 20 hypotheses lacking citations — quest c488a683-47f — P90 gap: 107 hypotheses lack evidence_for[Atlas] Score 30 paper artifacts with quality scoring — quest 415b277f-03b — P85 gap: 167 unscored artifacts[Forge] Add PubMed abstracts to 30 papers missing them — quest dd0487d3-38a — P82 gap: 228 papers lacking abstractsDuplicates blocked (already have open tasks):
What was done:
SELECT DISTINCT partner, partner_type FROM (subquery ORDER BY evidence_strength) pattern in _build_cell_infobox — the flat SELECT DISTINCT ... ORDER BY evidence_strength without selecting that column is rejected by PostgreSQL/compare?ids= links (were incorrectly changed to /compare%sids=)
SELECT DISTINCT partner, partner_type FROM (...) sub LIMIT 12 — PostgreSQL test: OKgrep 'compare%sids=' api.py — 0 occurrences (all restored to /compare?ids=)git diff origin/main..HEAD -- api.py — empty (api.py matches origin/main exactly)git diff HEAD -- api.py — only my two targeted fixes (no unintended changes)Queue state: 17 open + 8 running = 25 active SciDEX tasks (healthy: False, threshold=50)
[Agora] Score 13 unscored hypotheses → blocked (fcda018c exists)[Atlas] Add mermaid diagrams to 10 wiki entities → blocked (5a373c40 exists)[Forge] Add PubMed abstracts to 30 papers → blocked (f13984eb exists)[Atlas] Score 50 paper artifacts → blocked (ebade91a/6830d8b4 exist)Queue state: 38 open SciDEX tasks (below threshold 50, but gaps covered)
Queue state: 48 open SciDEX one-shot tasks (threshold 50, at boundary)
Actions: Created 3 new tasks this cycle:
[Agora] Score 20 unscored hypotheses with composite scoring (id: 373eafae) — quest c488a683-47f — Agora gap: unscored hypotheses[Agora] Run 4-round debates for 20 high-priority analyses lacking transcripts (id: 8b84a1f5) — quest c488a683-47f — Agora gap: 30% debate coverage[Atlas] Bidirectional KG-Wiki navigation for top 50 entities (id: aabceea6) — quest 415b277f-03b — Atlas gap: KG-wiki cross-linkingDuplicates blocked (Orchestra MCP dedup):
Queue state: 0 open, 1 running SciDEX one-shot tasks (healthy: False, threshold=50)
Notes:
Queue state: 0 open SciDEX one-shot tasks (healthy: False, threshold=50)
/data/orchestra/orchestra.db → does not existprojects table (schema mismatch — quests not migrated to PG)Infrastructure issues:
/home/ubuntu/Orchestra/orchestra.db symlink → /data/orchestra/orchestra.db (absent)projects table missing from scidex PostgreSQL DBorchestra create CLIQueue state: 12 open SciDEX one-shot tasks (healthy: False, threshold=50)
/tmp/orchestra_data/orchestra.dbworker_exit_unclean — workers did the work but didn't call orchestra complete/tmp/orchestra_data/orchestra.db is accessible (42MB)Status: Exit cleanly. Queue below threshold but all gaps covered by existing (orphaned) tasks.
Queue state: 12 open SciDEX one-shot tasks before generation (healthy: False, threshold=50), 16 open after generation.
Issues fixed in quest_engine.py:
/home/ubuntu/Orchestra/orchestra.db points at missing /data/orchestra/orchestra.db; added fallback discovery for /tmp/orchestra_data/orchestra.db.kind, tags, related_task_ids, similarity_key, consolidated_into), causing similarity checks to fail before task creation; added an idempotent compatibility check that creates those columns/indexes when absent.wiki_pages.content; updated it to current PostgreSQL wiki_pages.content_md.create_task rejected kind="research"; generated tasks now use valid kind="content", and service errors are logged as failures instead of false "CREATED None" successes.python3 quest_engine.py; created 4 quest-tagged tasks:
47738a96-5797-48b7-b467-272c9309d0a9 — [Agora] Add PubMed evidence to 20 hypotheses lacking citationsc031203d-3e22-4ecf-a674-ba5f637e81bb — [Forge] Add PubMed abstracts to 30 papers missing themb17a40df-4d42-4cf3-8ddf-52fe7df82528 — [Atlas] Add mermaid diagrams to 10 wiki entity pages5d50e873-b636-46d2-b056-594ac7ea7a22 — [Atlas] Expand 10 wiki stubs with cited neurodegeneration contextVerification:
python3 -m py_compile quest_engine.py passes./tmp/orchestra_data/orchestra.db with status=open, task_type=one_shot, kind=content, quest IDs, tags, and spec paths.python3 quest_engine.py run blocked all 4 candidates by exact_title, creating 0 duplicates.{
"completion_shas": [
"b6ef46508"
],
"completion_shas_checked_at": "2026-04-21T04:33:08.236839+00:00",
"_watchdog_repair_task_id": "1fd42f17-02b4-4cc6-a247-cf87150eabd4",
"_watchdog_repair_created_at": "2026-04-22T20:06:43.678495+00:00",
"requirements": {
"reasoning": 8,
"analysis": 7
},
"_stall_skip_providers": [
"glm"
]
}