{"quest":{"id":"q-code-health","name":"Code Health","description":"Continuous code quality review without removing functionality. Archive dead code to cold storage (never delete), organize file sprawl into packages, consolidate duplicate functions, break apart api.py. Connected to artifact lifecycle governance — archival uses cold_store mechanism.","layer":"Senate","priority":88,"status":"active","created_at":"2026-04-03 23:17:24","updated_at":"2026-04-04 00:06:01"},"tasks":[{"id":"2e7f22a0-6730-4c8e-bb69-a0c06fb77e15","title":"[Senate] Recurring code health sweep","description":"Periodic (weekly) conservative code quality review. Scan for: dead code (unreferenced files, version-suffixed duplicates), code duplication (duplicate function definitions, copy-paste patterns), sprawl (root-level file count, god files), missing tests. Produce a prioritized findings report. NEVER remove code without verifying it is truly unused. NEVER destabilize the system.","status":"open","priority":94,"frequency":"every-12h","max_iterations":null,"assigned_slot":"","started_at":null,"completed_at":"2026-04-28T20:46:33.924428+00:00","updated_at":"2026-04-28T20:46:33.924428+00:00","summary":"","completion_summary":"**Code health sweep — Path B close**","completion_notes":"Auto-release: recurring task had no work this cycle","last_error":"","time_estimate_hours":0.0,"completion_count":1,"spec_path":"docs/planning/specs/2e7f22a0_673_code_health_sweep_spec.md","provider":"any","payload_json":"{\"requirements\": {\"coding\": 7, \"reasoning\": 6, \"safety\": 8}, \"completion_shas\": [\"afacf3ce1d194f4a35f32e21f984142ef99fb44a\", \"ac78a2f85e5e933f874741e3434845218e50312e\"], \"completion_shas_checked_at\": \"2026-04-12T19:02:20.119517+00:00\", \"completion_shas_missing\": [\"fdc3aa5d62851f13d5439220e315d874f25ae3d1\", \"14c1fb547a816a5e1847097267d5881c462e854b\", \"313665a15cf2f8015ecf9d5a6a9ca83875d1d704\", \"eae88887d598f851526a528f34fdcce971740589\", \"dd3fa66411aa824c759958a258b5d835cb47c71c\", \"6c008b204d0462985a40a8da56675a5e02693f34\", \"e997e6fa101bde3f3620d516a740b6148e8a9876\", \"a1d9245f4d5ff5a6454190bcd41ebb8db4df2ec7\", \"595b4c5832de68a61f04f07903c6f73eb9f753cd\", \"d28f4b208c6eb2e5a1e71df5e86a065dbedaa984\", \"24b6b3bceb967b03b242cfbb89b2c29f6da4771e\", \"7b112933bcedb6665493f8751da303604b9d66c9\", \"d380c7658efcd4c3f8df809954bf263e7f2ac02a\", \"3771e4f05fe0002d5c319b525fc293078d1458cb\", \"b54878be3a6274e675ddc5fce04f04b205757acc\", \"5d3f31efadeca1dc23af7b0e4bf9eed9e8f74222\", \"42abe5188d706b36bbe25946232a6dd6868deb8b\", \"3b31504421c3d3c5a11f59c48f9ec6cdd1753d29\", \"7eefd067e2612f49b12b1839b808c8817f03ea5d\", \"2f926e27ac59ae5097f2a38a04430fdb3d8a5cdd\", \"d63360deb1e45f8b317f908130ad637a085cab9b\", \"814a897a2212e40b1c28c4ec8c7d65e7660305d9\", \"b9f2918b6adea9d3f50110a52faca35141bb9063\", \"a28f92518ac86273cbeccd6841a7390a8986b78f\", \"1e775556c69176a8d019816c05a43ae389079fd2\", \"742cb90b572dcccb9e88f777183569f80948c55c\", \"ce24b1ab5d61e2a71da86e42436dfc93f8d1dc58\", \"9afc32f4b18248bc470041361c50df8b260dffeb\", \"ba830e33fa0172c70f21863335f659f4f44ae975\", \"c1d8ee1d6b22ac65f3142a475c5c1292933a6164\", \"5e6b44524b9a29802f81c60dc8957eb713198401\", \"fe717978854cb86cad07fecb53ba09c3fc4e5d5c\", \"7914f6ccd514f7a27497cabc85257dcc0c0bd33e\", \"9bfde4fa4fc65f4e0c31fab0341e84e985e468b1\", \"0e0079b2008098e66d344d195f1bd32af68e7728\", \"e55f9e02fe513938f2756b9c810c1766a44b7fac\", \"fe7bacd298ad7cbd60607cd2870d87a15cd61986\", \"61e3040760ac5c93bc7501efe5c6816d0552d898\", \"3324b6258c9d30b1936dbb1e97efe7aa763fdde2\", \"4014e957f89f9e8aad652b35034a2da68f9d8801\", \"1f318c520ee52a0b3a5780c21a24364965acbcbf\", \"ba9ff0e184265c58893c28462981db498c5dedc3\", \"861ecd145e420ddf29608885235b712394c62050\", \"e69c174620fc8fdadacab69d369b664772255319\", \"1269a4bd9675edfc90f0791ddcfc5cd7e1f44254\", \"d46172b20ed530a33b51153bbd978e5e7556f9a0\", \"f8e72b8bea7720ad945a58016647cb3784479fd2\", \"103e818b4ec11077ad11bc9544bdb4f51c7e37e0\", \"a5fbe0d618c7109ca3794ad682acbca1be6d4cf6\", \"0327dcb4245c0828e11a7e7a59f858bb6f653957\", \"4edceafdb38d5e5161d9837fe57ef80f04a1b295\", \"62cc000d7bace881a688e46fcde225927226f26c\", \"6c5ce2a2bd0261201175d86613833fc82ba60399\", \"23b411ea5964db9ad2174e07a0260ec807ace7c2\", \"3734b023147466f2c38bc120710bfe30a59f6e85\", \"2ab8862d32e74a849c2dd5501c6f4eb20542872a\", \"756a85a6420a22b3cd9fe8376dfa91c0f6360589\", \"7d72467b24d2471c89620b3ba8fc61feed55c0e1\", \"5a80fdf3061aebd88217ce4503fa6b2765393cf9\", \"5ae538a527c033e1f6a05c444596d2813daeb5c0\", \"2dcdc555717e69dc341fd560f5aec81c7e5aa5a0\", \"d496b92eb4f5ad5c65f7d43e5591d00bf2fa6bec\", \"563881398dd8de3764da7136183170239cc81382\", \"36f72f3b8d4b0d7c4066355843041ddaac66e30f\", \"0b59e608efaefcc78c65c7da30a748d0da822f2b\", \"7950fba2d004c236a6d6ac814eff149a36d86a2a\", \"86566572db04e44d3a1a3a4548e5796403577ce7\", \"4153baabaca069b4b3685ed2aef034aedc48ad6a\", \"ce505765f65222502ef247463a82eefa20f8b367\", \"fa4a1cd6f5b7e2df1638be0e451f6941de57f45b\", \"5fb424867db4c46a63f79f38d8e08a19871cfe6e\", \"d6fb93b3d598ba76a463af0fdd8ac25c2321338a\", \"854e59b2f8a5e4e0a957daa18e4b5bca2aaf57d6\", \"44810968d1304fdb1d4bfe610512f271c322126f\", \"86ee381282779d0acd8c1c89cd14654fee2e31c0\", \"bd4bd7d2b7f4ffc83d39f0fa7760436fc77dba7f\", \"28a7d900175fe48627aba9623b0aa6c12f47246a\", \"cc9d81f2cf095553cf7b80ef37003bf3ecc82215\", \"01dc7002e80eb3aa88a8416c72edeac81b909556\", \"ff5b5a5351675999c1f658a8ae6f19e5bca98ff3\", \"8fe712d8bf5bb4b95f54e309106d4f98ce3027de\", \"dc974435f1dc21ca1a6d98d6a36103c35849abd9\", \"5fa6dc6b194f29aea22905e182b0dde66256ba1c\", \"037255fb8e4bf35936a3cdb7d7a5d6a741da3ad0\", \"92e19eb46dc32186d9224c576ad9336571a3e4a4\", \"08835dbbe47958d6d00acca436cd75a21ac39114\", \"d7efb7504f84b693580fad204bdda33b99958e0e\", \"98bafa3e94904c341b986365fc1bde4cde477e51\", \"630f0b3788cb088744f0b3dccaccca27684d25cd\", \"32133335670f9d041c8f07d4e7854810ab672e6c\", \"a3cea1f017fb3131546e2b34042b54fad8073b90\", \"525517c9e454e06f8c37cf0198808aec1e1bfdf8\", \"3e733ca3b3c3fb93a94e58f1a11947a5ff61be7f\", \"b3088d5ee418286be83653993ee1ace342c6b23b\", \"deb6644bb1156f267f8985200b9b4743f017f586\", \"3bf304c0d9ddbea97cc06a26683841a0b30cac4a\", \"5133b73654452d5cc8ac6c7e0aa4734e54bbbcd4\", \"f7af5dee1bcbc9022c2eeaa0646bfab38e794111\", \"1621d2e564479a0f06fa775a1c0c3de7c1526473\", \"dbae52b1ecbbef881f6d65ea525588e3353410e2\", \"a8b49f17d8d91d93ddbc94f4dd30b96a262dda76\", \"1670f74065c3eeb51aad182aad4c713b7f4f8a56\", \"5c79cc792bc00840f19fc298a00d26a24b6d6c17\", \"88f4a3cd4ea81d63465010441e12b91b6279be00\", \"e6f0a0d3de27294262630af8a526fc3cb573effe\", \"db5edc52892944d6e50b03761a469d3073e08a63\", \"aad8306a91378c00c37230b01cd5ad57e2070a9b\", \"4113bd29b4074dc70e4deff019bac94a5270eb12\", \"3d5de17f63fe3d68a779f6d72e13eaa5c102bae8\", \"d81660712b5154f0a685558f300dc83a7753b1e3\", \"ae9260bfbbc64e345950d3d87f51c772d1701154\", \"823d5ab437d3332a22bb433cb18b6f1402073d0e\", \"21fc384198d02e8c273add73d25c7eda4652a8bb\", \"6e07fce4567d0107e3ea107cd9029e8094a979c4\", \"fcf4647af3d10925c973690c0a3e42bcdffd813e\", \"c26bb486037db0b35fbfaf1485191496f6f8c34c\", \"1d27ee28604290ee3fdd704a15d0d2877a619131\", \"77cb65edbd55db02aaf8f46cd2c586a465836e6a\", \"c54cc175ed1bc634fbbddd32a30c78565450d989\", \"2f8914a51611d85dcbaac5830b89d571d358a432\", \"95cac3dd55290d165997c76e0cd45be9dc28a161\", \"01462f3fbad4315e4cfbdb712ead62b83aeb1b72\", \"d6d3176b0bf3fb4d23d5154373c46d287709a9ab\", \"4cc034e261e76577d6623d29a1499271eb7b6d82\", \"2184b4d1cbe55a273c34cf98bf27ef45cd81d728\", \"fddd070a35f4a8ea472293626e2aff2c5780ff73\", \"cf13d35cce27e945e3390f4e36922c95a9eabd24\", \"ceb0879505dc09a4a2b07e7783d38573ad49d67d\", \"8a409b3ee75c08fd1b4b74d1d6d5a675d9208b7a\", \"1ab886b1afd3b60285ef8f9b6189755b59783795\", \"99b1d99bc038c292a8d8137f0dccb4aec34c3d87\", \"58bc1ac1cef8358fa693298cba711f2ab037fd73\"]}","pr_links_json":"[]","commit_links_json":"[]","merge_commit_sha":null,"merge_verified_at":null,"verification_result":null,"verification_notes":null,"task_type":"recurring","pr_links":[],"commit_links":[]},{"id":"6ff1aaab-2f9c-47aa-ad10-26e87cec177b","title":"[Forge] Type-checked tool wrappers - pydantic gate + standard error envelope","description":"Wrap every tool in pydantic.validate_call + ToolResult{ok,data,error}; bucket validation vs upstream errors distinctly.","status":"open","priority":87,"frequency":"","max_iterations":null,"assigned_slot":"","started_at":null,"completed_at":null,"updated_at":"2026-05-16T04:12:40.706507+00:00","summary":"","completion_summary":"","completion_notes":"","last_error":"Reopened by done-evidence audit pass 2: legacy done row had no-progress/requeue summary and no completion evidence.","time_estimate_hours":0.0,"completion_count":0,"spec_path":"docs/planning/specs/q-devx-typed-tool-wrappers_spec.md","provider":"any","payload_json":"{\"completion_shas\": [\"1dc92d178\"], \"completion_shas_checked_at\": \"\"}","pr_links_json":"[]","commit_links_json":"[]","merge_commit_sha":null,"merge_verified_at":null,"verification_result":null,"verification_notes":null,"task_type":"one_shot","pr_links":[],"commit_links":[]},{"id":"229313c6-62f7-41e2-bfe2-320e30d3e02d","title":"[Senate] Deferred-work queue - move heavy ops out of request path","description":"Postgres-backed deferred_jobs table with SKIP LOCKED claim; migrate three inline heavy paths (mat refresh, mermaid lint, citation recompute).","status":"done","priority":92,"frequency":"","max_iterations":null,"assigned_slot":"","started_at":null,"completed_at":"2026-04-27T22:47:52.185710+00:00","updated_at":"2026-04-27T22:47:52.185710+00:00","summary":"","completion_summary":"The task has been completed and merged to main. Here's the closing summary:","completion_notes":"Auto-release: work already on origin/main","last_error":"","time_estimate_hours":0.0,"completion_count":0,"spec_path":"docs/planning/specs/q-perf-deferred-work-queue_spec.md","provider":"any","payload_json":"{\"_stall_skip_providers\": [\"glm\"]}","pr_links_json":"[]","commit_links_json":"[]","merge_commit_sha":null,"merge_verified_at":null,"verification_result":"pass","verification_notes":"The task has been completed and merged to main. Here's the closing summary:","task_type":"one_shot","pr_links":[],"commit_links":[]},{"id":"25f7f7f2-e05b-4c08-8414-492b5aa4ccaa","title":"[Senate] Hot-path query optimizer for top-20 endpoints","description":"Sampled per-route DB-time instrumentation + EXPLAIN-driven index suggestions; senate page; CI gate against new seq-scans on top-20 routes.","status":"done","priority":90,"frequency":"","max_iterations":null,"assigned_slot":"","started_at":null,"completed_at":"2026-04-27T14:52:45.356293+00:00","updated_at":"2026-04-27T14:52:45.356293+00:00","summary":"","completion_summary":"[Senate] Hot-path query optimizer: instrumentation, aggregator, senate page, CI gate [task:25f7f7f2-e05b-4c08-8414-492b5aa4ccaa]","completion_notes":"Auto-completed by supervisor after successful deploy to main","last_error":"","time_estimate_hours":0.0,"completion_count":0,"spec_path":"docs/planning/specs/q-perf-hot-path-optimizer_spec.md","provider":"any","payload_json":"{}","pr_links_json":"[]","commit_links_json":"[]","merge_commit_sha":null,"merge_verified_at":null,"verification_result":null,"verification_notes":null,"task_type":"one_shot","pr_links":[],"commit_links":[]},{"id":"6172a849-6ae0-484e-aac2-cdc240b5a3fc","title":"[Atlas] HTTP ETag layer with artifact-mutation-aware invalidation","description":"Add version+last_mutated columns to artifact tables, ETag middleware on top GETs, FK-trigger invalidation when comments/scores change.","status":"done","priority":89,"frequency":"","max_iterations":null,"assigned_slot":"","started_at":null,"completed_at":"2026-04-27T22:43:05.164866+00:00","updated_at":"2026-04-27T22:43:05.164866+00:00","summary":"","completion_summary":"Already resolved in squash merge cc66abb4b (PR #834). The review-requested defensive fix (wrapping plain str cache hits in HTMLResponse before setting .headers[\"ETag\"]) is confirmed in origin/main's api_shared/etag_middleware.py at lines 71-72: `if isinstance(response, str): response = HTMLResponse(content=response)`. The squash merge commit message explicitly lists the defensive fix commit among the merged commits. All acceptance criteria except the optional frontend/load-evidence items are satisfied on main.","completion_notes":"","last_error":"","time_estimate_hours":0.0,"completion_count":0,"spec_path":"docs/planning/specs/q-perf-etag-smart-invalidation_spec.md","provider":"any","payload_json":"{}","pr_links_json":"[]","commit_links_json":"[]","merge_commit_sha":null,"merge_verified_at":null,"verification_result":"pass","verification_notes":"Verified by reading `git show origin/main:api_shared/etag_middleware.py` — isinstance check and HTMLResponse wrap are present. Squash merge cc66abb4b includes commit [Atlas] Defensively wrap str in HTMLResponse in add_etag_response [task:6172a849-6ae0-484e-aac2-cdc240b5a3fc].","task_type":"one_shot","pr_links":[],"commit_links":[]},{"id":"e58cdbeb-4317-494e-bfed-f101183b2a1a","title":"[Senate] Postgres pool autoscaler driven by concurrent-request load","description":"Histogram of pool-checkout-wait p95; resize psycopg-pool dynamically up to PG max_connections-5; cooldown, hard cap, freeze override.","status":"done","priority":88,"frequency":"","max_iterations":null,"assigned_slot":"","started_at":null,"completed_at":"2026-04-27T22:16:19.264393+00:00","updated_at":"2026-04-27T22:16:19.264393+00:00","summary":"","completion_summary":"[Senate] Update pool autoscaler spec with work log [task:e58cdbeb-4317-494e-bfed-f101183b2a1a]; [Senate] PG pool autoscaler driven by checkout-wait p95 [task:e58cdbeb-4317-494e-bfed-f101183b2a1a]","completion_notes":"Auto-completed by supervisor after successful deploy to main","last_error":"","time_estimate_hours":0.0,"completion_count":0,"spec_path":"docs/planning/specs/q-perf-pool-autoscaler_spec.md","provider":"any","payload_json":"{\"completion_shas\": [\"d64dcf6e0c50001ef37331ee821f377cbf43c7e3\", \"0a651d687d3f1448d4d3148a99a88b7f76a687df\"], \"completion_shas_checked_at\": \"\"}","pr_links_json":"[]","commit_links_json":"[]","merge_commit_sha":null,"merge_verified_at":null,"verification_result":null,"verification_notes":null,"task_type":"one_shot","pr_links":[],"commit_links":[]},{"id":"256e38e5-fc4f-4b92-91ec-0b1aa9ba180b","title":"[Senate] N+1 query detector + auto-batch helpers for hot paths","description":"Per-request query-template counter; senate dashboard of top offenders; batch_in/batch_lookup/prefetch helpers; pytest no_n_plus_one marker.","status":"done","priority":88,"frequency":"","max_iterations":null,"assigned_slot":"","started_at":null,"completed_at":"2026-04-27T15:44:54.008305+00:00","updated_at":"2026-04-27T15:44:54.008305+00:00","summary":"","completion_summary":"[Senate] N+1 query detector + auto-batch helpers (api.py, api_shared) [task:256e38e5-fc4f-4b92-91ec-0b1aa9ba180b]","completion_notes":"Auto-completed by supervisor after successful deploy to main","last_error":"","time_estimate_hours":0.0,"completion_count":0,"spec_path":"docs/planning/specs/q-perf-n-plus-one-detector_spec.md","provider":"any","payload_json":"{}","pr_links_json":"[]","commit_links_json":"[]","merge_commit_sha":null,"merge_verified_at":null,"verification_result":null,"verification_notes":null,"task_type":"one_shot","pr_links":[],"commit_links":[]},{"id":"6a532994-7b9d-4a77-a85e-d0c596f2779b","title":"[Senate] Break apart api.py god file into focused modules","description":"api.py is 30K lines — a monolithic god file. Extract logical sections into focused modules while preserving all functionality. Candidates: route handlers by layer (agora_routes.py, exchange_routes.py, atlas_routes.py, senate_routes.py, forge_routes.py), shared HTML helpers (html_helpers.py), database queries (db_queries.py). Use FastAPI APIRouter for clean separation. Test every endpoint after each extraction.\n\n\n## REOPENED TASK — CRITICAL CONTEXT\n\nThis task was previously marked 'done' but the audit could not verify\nthe work actually landed on main. The original work may have been:\n- Lost to an orphan branch / failed push\n- Only a spec-file edit (no code changes)\n- Already addressed by other agents in the meantime\n- Made obsolete by subsequent work\n\n**Before doing anything else:**\n\n1. **Re-evaluate the task in light of CURRENT main state.** Read the\n   spec and the relevant files on origin/main NOW. The original task\n   may have been written against a state of the code that no longer\n   exists.\n\n2. **Verify the task still advances SciDEX's aims.** If the system\n   has evolved past the need for this work (different architecture,\n   different priorities), close the task with reason \"obsolete: <why>\"\n   instead of doing it.\n\n3. **Check if it's already done.** Run `git log --grep='<task-id>'`\n   and read the related commits. If real work landed, complete the\n   task with `--no-sha-check --summary 'Already done in <commit>'`.\n\n4. **Make sure your changes don't regress recent functionality.** Many\n   agents have been working on this codebase. Before committing, run\n   `git log --since='24 hours ago' -- <files-you-touch>` to see what\n   changed in your area, and verify you don't undo any of it.\n\n5. **Stay scoped.** Only do what this specific task asks for. Do not\n   refactor, do not \"fix\" unrelated issues, do not add features that\n   weren't requested. Scope creep at this point is regression risk.\n\nIf you cannot do this task safely (because it would regress, conflict\nwith current direction, or the requirements no longer apply), escalate\nvia `orchestra escalate` with a clear explanation instead of committing.\n","status":"done","priority":87,"frequency":"","max_iterations":null,"assigned_slot":"","started_at":null,"completed_at":"2026-04-19T02:34:07.917875+00:00","updated_at":"2026-04-19T02:34:07.917875+00:00","summary":"","completion_summary":"[Senate] Document api.py modularization analysis findings [task:6a532994-7b9d-4a77-a85e-d0c596f2779b]","completion_notes":"Auto-completed by supervisor after successful deploy to main","last_error":"","time_estimate_hours":0.0,"completion_count":0,"spec_path":"docs/planning/specs/6a532994_7b9_spec.md","provider":"any","payload_json":"{\"requirements\": {\"coding\": 7, \"reasoning\": 6}, \"_reset_note\": \"This task was reset after a database incident on 2026-04-17.\\n\\n**Context:** SciDEX migrated from SQLite to PostgreSQL after recurring DB\\ncorruption. Some work done during Apr 16-17 may have been lost.\\n\\n**Before starting work:**\\n1. Check if the task's goal is ALREADY satisfied (run the relevant checks)\\n2. Check `git log --all --grep=task:YOUR_TASK_ID` for prior commits\\n3. If complete, verify and mark done. If partial, continue. If not done, proceed.\\n\\n**DB change:** SciDEX now uses PostgreSQL. `get_db()` auto-detects via\\nSCIDEX_DB_BACKEND=postgres env var.\", \"_reset_at\": \"2026-04-18T06:29:22.046013+00:00\", \"_reset_from_status\": \"done\"}","pr_links_json":"[]","commit_links_json":"[]","merge_commit_sha":null,"merge_verified_at":null,"verification_result":null,"verification_notes":null,"task_type":"one_shot","pr_links":[],"commit_links":[]},{"id":"00b6c032-111f-4f19-aaf0-6a72c7346ef3","title":"[Senate] Audit and archive versioned dead code","description":"27+ files with _v[N] suffixes (expand_kg_v3-v11, enrich_seaad_v4, add_mermaid_v3, etc.). For each: check git blame to find when superseded, verify no imports reference it, verify no cron/systemd uses it. Move confirmed dead files to archive/ directory (don't delete — preserve history). Also check scripts/ for duplicates of root-level files.\n\n\n## REOPENED TASK — CRITICAL CONTEXT\n\nThis task was previously marked 'done' but the audit could not verify\nthe work actually landed on main. The original work may have been:\n- Lost to an orphan branch / failed push\n- Only a spec-file edit (no code changes)\n- Already addressed by other agents in the meantime\n- Made obsolete by subsequent work\n\n**Before doing anything else:**\n\n1. **Re-evaluate the task in light of CURRENT main state.** Read the\n   spec and the relevant files on origin/main NOW. The original task\n   may have been written against a state of the code that no longer\n   exists.\n\n2. **Verify the task still advances SciDEX's aims.** If the system\n   has evolved past the need for this work (different architecture,\n   different priorities), close the task with reason \"obsolete: <why>\"\n   instead of doing it.\n\n3. **Check if it's already done.** Run `git log --grep='<task-id>'`\n   and read the related commits. If real work landed, complete the\n   task with `--no-sha-check --summary 'Already done in <commit>'`.\n\n4. **Make sure your changes don't regress recent functionality.** Many\n   agents have been working on this codebase. Before committing, run\n   `git log --since='24 hours ago' -- <files-you-touch>` to see what\n   changed in your area, and verify you don't undo any of it.\n\n5. **Stay scoped.** Only do what this specific task asks for. Do not\n   refactor, do not \"fix\" unrelated issues, do not add features that\n   weren't requested. Scope creep at this point is regression risk.\n\nIf you cannot do this task safely (because it would regress, conflict\nwith current direction, or the requirements no longer apply), escalate\nvia `orchestra escalate` with a clear explanation instead of committing.\n","status":"done","priority":85,"frequency":"","max_iterations":null,"assigned_slot":"","started_at":null,"completed_at":"2026-04-19T04:19:33.856423+00:00","updated_at":"2026-04-19T04:19:33.856423+00:00","summary":"","completion_summary":"[Verify] Audit and archive versioned dead code — FAIL [task:00b6c032-111f-4f19-aaf0-6a72c7346ef3]","completion_notes":"Auto-completed by supervisor after successful deploy to main","last_error":"","time_estimate_hours":0.0,"completion_count":0,"spec_path":"docs/planning/specs/00b6c032_111_spec.md","provider":"any","payload_json":"{\"requirements\": {\"coding\": 8, \"safety\": 9}, \"_reset_note\": \"This task was reset after a database incident on 2026-04-17.\\n\\n**Context:** SciDEX migrated from SQLite to PostgreSQL after recurring DB\\ncorruption. Some work done during Apr 16-17 may have been lost.\\n\\n**Before starting work:**\\n1. Check if the task's goal is ALREADY satisfied (run the relevant checks)\\n2. Check `git log --all --grep=task:YOUR_TASK_ID` for prior commits\\n3. If complete, verify and mark done. If partial, continue. If not done, proceed.\\n\\n**DB change:** SciDEX now uses PostgreSQL. `get_db()` auto-detects via\\nSCIDEX_DB_BACKEND=postgres env var.\", \"_reset_at\": \"2026-04-18T06:29:22.046013+00:00\", \"_reset_from_status\": \"done\"}","pr_links_json":"[]","commit_links_json":"[]","merge_commit_sha":null,"merge_verified_at":null,"verification_result":"pass","verification_notes":"[Verify] Audit and archive versioned dead code — FAIL [task:00b6c032-111f-4f19-aaf0-6a72c7346ef3]","task_type":"one_shot","pr_links":[],"commit_links":[]},{"id":"d0876690-7512-42ad-8848-389018a3b6bd","title":"[Senate] Postgres slow-query detector with remediation hints","description":"15-min cron pulling pg_stat_statements + EXPLAIN; suggests indexes for seq-scan offenders; auto-files Orchestra task.","status":"done","priority":84,"frequency":"","max_iterations":null,"assigned_slot":"","started_at":null,"completed_at":"2026-04-28T00:01:21.556489+00:00","updated_at":"2026-05-16T04:12:40.706507+00:00","summary":"","completion_summary":"[Senate] Postgres slow-query detector with remediation hints — migration, collector, Senate page, and 26 tests all committed and pushed [task:d0876690-7512-42ad-8848-389018a3b6bd]","completion_notes":"6 files changed, 1431 insertions. Migration enables pg_stat_statements + creates slow_query_history + history mirror. Collector script runs idempotently, computes deltas, generates remediation hints via EXPLAIN, and auto-files Orchestra tasks for persistent offenders (3 consecutive runs + 7-day cooldown). Senate page at /senate/slow-queries with modal, JSON API, and create-task button. 26 tests pass.","last_error":"","time_estimate_hours":0.0,"completion_count":0,"spec_path":"docs/planning/specs/q-obs-pg-slow-query-detector_spec.md","provider":"any","payload_json":"{}","pr_links_json":"[]","commit_links_json":"[]","merge_commit_sha":null,"merge_verified_at":null,"verification_result":"pass","verification_notes":"Legacy done-evidence audit pass 2 backfill: preserved historical done state with administrative/no-merge evidence from completion summary. Original summary: [Senate] Postgres slow-query detector with remediation hints — migration, collector, Senate page, and 26 tests all committed and pushed [task:d0876690-7512-42ad-8848-389018a3b6bd]","task_type":"one_shot","pr_links":[],"commit_links":[]},{"id":"eb06d3df-8328-49ce-a959-06e16002550d","title":"[Senate] scidex doctor - diagnose common dev-env issues","description":"15 health probes (PG, submodules, secrets, services, claude CLI, migrations) with PASS/FAIL/FIX commands; --json.","status":"done","priority":84,"frequency":"","max_iterations":null,"assigned_slot":"","started_at":null,"completed_at":"2026-04-27T23:53:29.467254+00:00","updated_at":"2026-04-27T23:53:29.467254+00:00","summary":"","completion_summary":"[Senate] scidex doctor — 15 health probes for dev-env diagnostics [task:eb06d3df-8328-49ce-a959-06e16002550d]","completion_notes":"Auto-completed by supervisor after successful deploy to main","last_error":"","time_estimate_hours":0.0,"completion_count":0,"spec_path":"docs/planning/specs/q-devx-scidex-doctor_spec.md","provider":"any","payload_json":"{}","pr_links_json":"[]","commit_links_json":"[]","merge_commit_sha":null,"merge_verified_at":null,"verification_result":null,"verification_notes":null,"task_type":"one_shot","pr_links":[],"commit_links":[]},{"id":"18157380-138a-4c4f-a642-4d0ef5af3b4a","title":"[Senate] Consolidate database connection patterns","description":"48 files define their own get_db(), 287 files use raw sqlite3.connect(). Create shared database.py module with: get_db() for read-heavy (WAL, busy_timeout), get_db_write() for write operations, connection pooling context manager. Migrate high-traffic files first (api.py, agent.py, orchestrator, exchange, market_dynamics). Leave standalone scripts for later.\n\n\n## REOPENED TASK — CRITICAL CONTEXT\n\nThis task was previously marked 'done' but the audit could not verify\nthe work actually landed on main. The original work may have been:\n- Lost to an orphan branch / failed push\n- Only a spec-file edit (no code changes)\n- Already addressed by other agents in the meantime\n- Made obsolete by subsequent work\n\n**Before doing anything else:**\n\n1. **Re-evaluate the task in light of CURRENT main state.** Read the\n   spec and the relevant files on origin/main NOW. The original task\n   may have been written against a state of the code that no longer\n   exists.\n\n2. **Verify the task still advances SciDEX's aims.** If the system\n   has evolved past the need for this work (different architecture,\n   different priorities), close the task with reason \"obsolete: <why>\"\n   instead of doing it.\n\n3. **Check if it's already done.** Run `git log --grep='<task-id>'`\n   and read the related commits. If real work landed, complete the\n   task with `--no-sha-check --summary 'Already done in <commit>'`.\n\n4. **Make sure your changes don't regress recent functionality.** Many\n   agents have been working on this codebase. Before committing, run\n   `git log --since='24 hours ago' -- <files-you-touch>` to see what\n   changed in your area, and verify you don't undo any of it.\n\n5. **Stay scoped.** Only do what this specific task asks for. Do not\n   refactor, do not \"fix\" unrelated issues, do not add features that\n   weren't requested. Scope creep at this point is regression risk.\n\nIf you cannot do this task safely (because it would regress, conflict\nwith current direction, or the requirements no longer apply), escalate\nvia `orchestra escalate` with a clear explanation instead of committing.\n","status":"done","priority":84,"frequency":"","max_iterations":null,"assigned_slot":"","started_at":null,"completed_at":"2026-04-19T05:20:38.033554+00:00","updated_at":"2026-04-19T05:20:38.033554+00:00","summary":"","completion_summary":"[Senate] Update spec: fix verification work log [task:18157380-138a-4c4f-a642-4d0ef5af3b4a]; [Senate] Fix import for database.get_db calls in exchange.py [task:18157380-138a-4c4f-a642-4d0ef5af3b4a]; [Verify] exchange.py migration: add verification work log [task:18157380-138a-4c4f-a642-4d0ef5af3b4a]","completion_notes":"Auto-completed by supervisor after successful deploy to main","last_error":"","time_estimate_hours":0.0,"completion_count":0,"spec_path":"docs/planning/specs/18157380_138_spec.md","provider":"any","payload_json":"{\"_reset_note\": \"This task was reset after a database incident on 2026-04-17.\\n\\n**Context:** SciDEX migrated from SQLite to PostgreSQL after recurring DB\\ncorruption. Some work done during Apr 16-17 may have been lost.\\n\\n**Before starting work:**\\n1. Check if the task's goal is ALREADY satisfied (run the relevant checks)\\n2. Check `git log --all --grep=task:YOUR_TASK_ID` for prior commits\\n3. If complete, verify and mark done. If partial, continue. If not done, proceed.\\n\\n**DB change:** SciDEX now uses PostgreSQL. `get_db()` auto-detects via\\nSCIDEX_DB_BACKEND=postgres env var.\", \"_reset_at\": \"2026-04-18T06:29:22.046013+00:00\", \"_reset_from_status\": \"done\"}","pr_links_json":"[]","commit_links_json":"[]","merge_commit_sha":null,"merge_verified_at":null,"verification_result":null,"verification_notes":null,"task_type":"one_shot","pr_links":[],"commit_links":[]},{"id":"a1e536d4-8c81-4e0b-b17e-2deae4e2b4c2","title":"[Senate] Consolidate duplicated utility functions","description":"Multiple functions are defined 7-15 times across codebase: search_pubmed() (15x), extract_edges_from_abstract() (12x), classify_relation() (9x), find_entities_in_text() (8x), generate_mermaid() (7x). Create shared modules: pubmed_utils.py, kg_extraction_utils.py, mermaid_utils.py. Replace duplicates with imports. Verify each replacement doesn't break callers.\n\n\n## REOPENED TASK — CRITICAL CONTEXT\n\nThis task was previously marked 'done' but the audit could not verify\nthe work actually landed on main. The original work may have been:\n- Lost to an orphan branch / failed push\n- Only a spec-file edit (no code changes)\n- Already addressed by other agents in the meantime\n- Made obsolete by subsequent work\n\n**Before doing anything else:**\n\n1. **Re-evaluate the task in light of CURRENT main state.** Read the\n   spec and the relevant files on origin/main NOW. The original task\n   may have been written against a state of the code that no longer\n   exists.\n\n2. **Verify the task still advances SciDEX's aims.** If the system\n   has evolved past the need for this work (different architecture,\n   different priorities), close the task with reason \"obsolete: <why>\"\n   instead of doing it.\n\n3. **Check if it's already done.** Run `git log --grep='<task-id>'`\n   and read the related commits. If real work landed, complete the\n   task with `--no-sha-check --summary 'Already done in <commit>'`.\n\n4. **Make sure your changes don't regress recent functionality.** Many\n   agents have been working on this codebase. Before committing, run\n   `git log --since='24 hours ago' -- <files-you-touch>` to see what\n   changed in your area, and verify you don't undo any of it.\n\n5. **Stay scoped.** Only do what this specific task asks for. Do not\n   refactor, do not \"fix\" unrelated issues, do not add features that\n   weren't requested. Scope creep at this point is regression risk.\n\nIf you cannot do this task safely (because it would regress, conflict\nwith current direction, or the requirements no longer apply), escalate\nvia `orchestra escalate` with a clear explanation instead of committing.\n","status":"done","priority":82,"frequency":"","max_iterations":null,"assigned_slot":"","started_at":null,"completed_at":"2026-04-19T05:55:12.739744+00:00","updated_at":"2026-04-19T05:55:12.739744+00:00","summary":"","completion_summary":"[Senate] Update spec work log: resolve merge failure, document rebase [task:a1e536d4-8c81-4e0b-b17e-2deae4e2b4c2]; [Senate] Update spec work log: consolidate 2 more kg_expansion files [task:a1e536d4-8c81-4e0b-b17e-2deae4e2b4c2]; [Senate] Consolidate duplicate extraction functions in kg_expansion [task:a1e536d4-8c81-4e0b-b17e-2deae4e2b4c2]","completion_notes":"Auto-completed by supervisor after successful deploy to main","last_error":"","time_estimate_hours":0.0,"completion_count":0,"spec_path":"docs/planning/specs/a1e536d4_8c8_spec.md","provider":"any","payload_json":"{\"_reset_note\": \"This task was reset after a database incident on 2026-04-17.\\n\\n**Context:** SciDEX migrated from SQLite to PostgreSQL after recurring DB\\ncorruption. Some work done during Apr 16-17 may have been lost.\\n\\n**Before starting work:**\\n1. Check if the task's goal is ALREADY satisfied (run the relevant checks)\\n2. Check `git log --all --grep=task:YOUR_TASK_ID` for prior commits\\n3. If complete, verify and mark done. If partial, continue. If not done, proceed.\\n\\n**DB change:** SciDEX now uses PostgreSQL. `get_db()` auto-detects via\\nSCIDEX_DB_BACKEND=postgres env var.\", \"_reset_at\": \"2026-04-18T06:29:22.046013+00:00\", \"_reset_from_status\": \"done\"}","pr_links_json":"[]","commit_links_json":"[]","merge_commit_sha":null,"merge_verified_at":null,"verification_result":null,"verification_notes":null,"task_type":"one_shot","pr_links":[],"commit_links":[]},{"id":"2eff3b68-7406-412f-8f40-1ce1035b546b","title":"[Senate] Organize root-level file sprawl into packages","description":"305 Python files at root level. Organize into logical packages: enrichment/ (68 enrich_*.py), kg_expansion/ (28 expand_kg_*.py), backfill/ (13 backfill_*.py), mermaid/ (11 add_mermaid_*.py). Keep core files at root (api.py, agent.py, cli.py, etc.). Update all imports. Fix scripts/ duplicates.\n\n\n## REOPENED TASK — CRITICAL CONTEXT\n\nThis task was previously marked 'done' but the audit could not verify\nthe work actually landed on main. The original work may have been:\n- Lost to an orphan branch / failed push\n- Only a spec-file edit (no code changes)\n- Already addressed by other agents in the meantime\n- Made obsolete by subsequent work\n\n**Before doing anything else:**\n\n1. **Re-evaluate the task in light of CURRENT main state.** Read the\n   spec and the relevant files on origin/main NOW. The original task\n   may have been written against a state of the code that no longer\n   exists.\n\n2. **Verify the task still advances SciDEX's aims.** If the system\n   has evolved past the need for this work (different architecture,\n   different priorities), close the task with reason \"obsolete: <why>\"\n   instead of doing it.\n\n3. **Check if it's already done.** Run `git log --grep='<task-id>'`\n   and read the related commits. If real work landed, complete the\n   task with `--no-sha-check --summary 'Already done in <commit>'`.\n\n4. **Make sure your changes don't regress recent functionality.** Many\n   agents have been working on this codebase. Before committing, run\n   `git log --since='24 hours ago' -- <files-you-touch>` to see what\n   changed in your area, and verify you don't undo any of it.\n\n5. **Stay scoped.** Only do what this specific task asks for. Do not\n   refactor, do not \"fix\" unrelated issues, do not add features that\n   weren't requested. Scope creep at this point is regression risk.\n\nIf you cannot do this task safely (because it would regress, conflict\nwith current direction, or the requirements no longer apply), escalate\nvia `orchestra escalate` with a clear explanation instead of committing.\n","status":"done","priority":80,"frequency":"","max_iterations":null,"assigned_slot":"","started_at":null,"completed_at":"2026-04-19T05:53:32.801187+00:00","updated_at":"2026-04-19T05:53:32.801187+00:00","summary":"","completion_summary":"Update spec work log: reorganized root-level file sprawl [task:2eff3b68-7406-412f-8f40-1ce1035b546b]; [Senate] Organize root-level file sprawl into packages [task:2eff3b68-7406-412f-8f40-1ce1035b546b]","completion_notes":"Auto-completed by supervisor after successful deploy to main","last_error":"","time_estimate_hours":0.0,"completion_count":0,"spec_path":"docs/planning/specs/2eff3b68_740_spec.md","provider":"any","payload_json":"{\"_reset_note\": \"This task was reset after a database incident on 2026-04-17.\\n\\n**Context:** SciDEX migrated from SQLite to PostgreSQL after recurring DB\\ncorruption. Some work done during Apr 16-17 may have been lost.\\n\\n**Before starting work:**\\n1. Check if the task's goal is ALREADY satisfied (run the relevant checks)\\n2. Check `git log --all --grep=task:YOUR_TASK_ID` for prior commits\\n3. If complete, verify and mark done. If partial, continue. If not done, proceed.\\n\\n**DB change:** SciDEX now uses PostgreSQL. `get_db()` auto-detects via\\nSCIDEX_DB_BACKEND=postgres env var.\", \"_reset_at\": \"2026-04-18T06:29:22.046013+00:00\", \"_reset_from_status\": \"done\"}","pr_links_json":"[]","commit_links_json":"[]","merge_commit_sha":null,"merge_verified_at":null,"verification_result":null,"verification_notes":null,"task_type":"one_shot","pr_links":[],"commit_links":[]},{"id":"9076b7ed-f770-4a79-aff9-5e8946118045","title":"[Senate] Add linting and formatting infrastructure","description":"Add pyproject.toml with ruff config (conservative — only flag clear issues, not style preferences). Add ruff check to quality_gates.py pre-merge gate. Focus on: unused imports, undefined variables, f-string issues, security issues (S101-S110). Do NOT enforce style formatting initially — too disruptive.\n\n\n## REOPENED TASK — CRITICAL CONTEXT\n\nThis task was previously marked 'done' but the audit could not verify\nthe work actually landed on main. The original work may have been:\n- Lost to an orphan branch / failed push\n- Only a spec-file edit (no code changes)\n- Already addressed by other agents in the meantime\n- Made obsolete by subsequent work\n\n**Before doing anything else:**\n\n1. **Re-evaluate the task in light of CURRENT main state.** Read the\n   spec and the relevant files on origin/main NOW. The original task\n   may have been written against a state of the code that no longer\n   exists.\n\n2. **Verify the task still advances SciDEX's aims.** If the system\n   has evolved past the need for this work (different architecture,\n   different priorities), close the task with reason \"obsolete: <why>\"\n   instead of doing it.\n\n3. **Check if it's already done.** Run `git log --grep='<task-id>'`\n   and read the related commits. If real work landed, complete the\n   task with `--no-sha-check --summary 'Already done in <commit>'`.\n\n4. **Make sure your changes don't regress recent functionality.** Many\n   agents have been working on this codebase. Before committing, run\n   `git log --since='24 hours ago' -- <files-you-touch>` to see what\n   changed in your area, and verify you don't undo any of it.\n\n5. **Stay scoped.** Only do what this specific task asks for. Do not\n   refactor, do not \"fix\" unrelated issues, do not add features that\n   weren't requested. Scope creep at this point is regression risk.\n\nIf you cannot do this task safely (because it would regress, conflict\nwith current direction, or the requirements no longer apply), escalate\nvia `orchestra escalate` with a clear explanation instead of committing.\n","status":"done","priority":78,"frequency":"","max_iterations":null,"assigned_slot":"","started_at":null,"completed_at":"2026-04-19T10:35:15.003456+00:00","updated_at":"2026-04-19T10:35:15.003456+00:00","summary":"","completion_summary":"[Senate] Fix ruff config for modern ruff, remove dead imports [task:9076b7ed-f770-4a79-aff9-5e8946118045]","completion_notes":"Auto-completed by supervisor after successful deploy to main","last_error":"","time_estimate_hours":0.0,"completion_count":0,"spec_path":"docs/planning/specs/9076b7ed_f77_spec.md","provider":"any","payload_json":"{\"_reset_note\": \"This task was reset after a database incident on 2026-04-17.\\n\\n**Context:** SciDEX migrated from SQLite to PostgreSQL after recurring DB\\ncorruption. Some work done during Apr 16-17 may have been lost.\\n\\n**Before starting work:**\\n1. Check if the task's goal is ALREADY satisfied (run the relevant checks)\\n2. Check `git log --all --grep=task:YOUR_TASK_ID` for prior commits\\n3. If complete, verify and mark done. If partial, continue. If not done, proceed.\\n\\n**DB change:** SciDEX now uses PostgreSQL. `get_db()` auto-detects via\\nSCIDEX_DB_BACKEND=postgres env var.\", \"_reset_at\": \"2026-04-18T06:29:22.046013+00:00\", \"_reset_from_status\": \"done\"}","pr_links_json":"[]","commit_links_json":"[]","merge_commit_sha":null,"merge_verified_at":null,"verification_result":null,"verification_notes":null,"task_type":"one_shot","pr_links":[],"commit_links":[]},{"id":"b350bf85-ce27-421a-97a7-dfabb488e650","title":"[Senate] Fix migration numbering and cleanup","description":"Fix migration number collisions: 002_add_resource_cost.py vs 002_add_resource_tracking.py, 025_add_backup_log_table.sql vs 025_add_last_evidence_update.py. Ensure migration_history table is consistent. Remove duplicate scripts/ copies of migration files.\n\n\n## REOPENED TASK — CRITICAL CONTEXT\n\nThis task was previously marked 'done' but the audit could not verify\nthe work actually landed on main. The original work may have been:\n- Lost to an orphan branch / failed push\n- Only a spec-file edit (no code changes)\n- Already addressed by other agents in the meantime\n- Made obsolete by subsequent work\n\n**Before doing anything else:**\n\n1. **Re-evaluate the task in light of CURRENT main state.** Read the\n   spec and the relevant files on origin/main NOW. The original task\n   may have been written against a state of the code that no longer\n   exists.\n\n2. **Verify the task still advances SciDEX's aims.** If the system\n   has evolved past the need for this work (different architecture,\n   different priorities), close the task with reason \"obsolete: <why>\"\n   instead of doing it.\n\n3. **Check if it's already done.** Run `git log --grep='<task-id>'`\n   and read the related commits. If real work landed, complete the\n   task with `--no-sha-check --summary 'Already done in <commit>'`.\n\n4. **Make sure your changes don't regress recent functionality.** Many\n   agents have been working on this codebase. Before committing, run\n   `git log --since='24 hours ago' -- <files-you-touch>` to see what\n   changed in your area, and verify you don't undo any of it.\n\n5. **Stay scoped.** Only do what this specific task asks for. Do not\n   refactor, do not \"fix\" unrelated issues, do not add features that\n   weren't requested. Scope creep at this point is regression risk.\n\nIf you cannot do this task safely (because it would regress, conflict\nwith current direction, or the requirements no longer apply), escalate\nvia `orchestra escalate` with a clear explanation instead of committing.\n","status":"done","priority":76,"frequency":"","max_iterations":null,"assigned_slot":"","started_at":null,"completed_at":"2026-04-19T10:56:41.068568+00:00","updated_at":"2026-04-19T10:56:41.068568+00:00","summary":"","completion_summary":"[Verify] Migration numbering fix verified on main — already resolved [task:b350bf85-ce27-421a-97a7-dfabb488e650]; [Senate] Fix migration number collisions and remove duplicates [task:b350bf85-ce27-421a-97a7-dfabb488e650]; [Senate] Implement automated task quality scoring [task:dcf8f1f1-4a41-4820-b377-2218cce3df29]","completion_notes":"Auto-completed by supervisor after successful deploy to main","last_error":"","time_estimate_hours":0.0,"completion_count":0,"spec_path":"docs/planning/specs/b350bf85_ce2_spec.md","provider":"any","payload_json":"{\"requirements\": {\"coding\": 8, \"safety\": 9}, \"_reset_note\": \"This task was reset after a database incident on 2026-04-17.\\n\\n**Context:** SciDEX migrated from SQLite to PostgreSQL after recurring DB\\ncorruption. Some work done during Apr 16-17 may have been lost.\\n\\n**Before starting work:**\\n1. Check if the task's goal is ALREADY satisfied (run the relevant checks)\\n2. Check `git log --all --grep=task:YOUR_TASK_ID` for prior commits\\n3. If complete, verify and mark done. If partial, continue. If not done, proceed.\\n\\n**DB change:** SciDEX now uses PostgreSQL. `get_db()` auto-detects via\\nSCIDEX_DB_BACKEND=postgres env var.\", \"_reset_at\": \"2026-04-18T06:29:22.046013+00:00\", \"_reset_from_status\": \"done\"}","pr_links_json":"[]","commit_links_json":"[]","merge_commit_sha":null,"merge_verified_at":null,"verification_result":null,"verification_notes":null,"task_type":"one_shot","pr_links":[],"commit_links":[]}],"reviews":[],"effectiveness":{},"prs":[],"commits":[],"spec_content":"---\ntitle: \"Code Health — Conservative Quality, Consolidation & Dead Code Removal\"\ndescription: \"Recurring quest to continuously review SciDEX codebase for quality, sprawl, and consolidation\"\nstatus: active\npriority: 88\nlayer: Senate\nquest: q-code-health\n---\n\n# Quest: Code Health\n\n## Vision\n\nSciDEX grows fast — 367 Python files, 124K LOC, 30K-line god file, 48 duplicate\nfunction definitions. This quest applies conservative, continuous pressure to improve\ncode quality without removing important functionality or destabilizing the system.\n\n**Principles:**\n1. **Conservative first** — never remove code that might be in use; archive, don't delete\n2. **Verify before acting** — check git blame, imports, cron jobs, systemd before touching\n3. **Test after every change** — all pages return 200, services healthy, API responds\n4. **Incremental** — small, safe steps; never refactor everything at once\n5. **Never contradict SciDEX goals** — code health serves the mission, not the other way around\n\n## Current State (Baseline Metrics)\n\n| Metric | Current | Target |\n|--------|---------|--------|\n| Root-level Python files | 305 | <80 |\n| api.py line count | 30,283 | <5,000 (split into modules) |\n| Duplicate get_db() definitions | 48 | 1 (shared module) |\n| Duplicate search_pubmed() | 15 | 1 |\n| Duplicate extract_edges_from_abstract() | 12 | 1 |\n| Version-suffixed dead code files | 27+ | 0 (archived) |\n| Migration number collisions | 2 | 0 |\n| Linting config | None | ruff in pyproject.toml |\n| Test files | 7 (580 lines) | 20+ (2K+ lines) |\n| Files with raw sqlite3.connect() | 287 | <50 (core scripts only) |\n\n## 8 Tasks (Dependency Order)\n\n```\nRecurring Sweep ──> (informs priorities for all below)\n\nFix Migrations (independent, quick win)\n\nAdd Linting (independent, infrastructure)\n\nArchive Dead Code ──> Organize File Sprawl\n\nConsolidate DB Patterns ──┐\n                          ├──> Break Apart api.py\nConsolidate Utility Fns ──┘\n```\n\n## Safety Protocol\n\nEvery code health change MUST:\n\n1. **Check references** before removing/moving anything:\n   ```bash\n   # Is this file imported anywhere?\n   grep -r \"import filename\" --include=\"*.py\" .\n   grep -r \"from filename\" --include=\"*.py\" .\n   # Is it in a systemd service?\n   grep -r \"filename\" /etc/systemd/system/scidex-*.service\n   # Is it in a cron job?\n   crontab -l | grep filename\n   ```\n\n2. **Test after changes**:\n   ```bash\n   for page in / /exchange /analyses/ /graph /gaps /senate /forge; do\n     code=$(curl -s -o /dev/null -w '%{http_code}' \"http://localhost:8000${page}\")\n     echo \"${code} ${page}\"\n   done\n   curl -s http://localhost:8000/api/status | python3 -m json.tool\n   ```\n\n3. **Commit atomically** — one logical change per commit, easy to revert\n\n4. **Keep archive/** — moved files go to `archive/` directory, not deleted\n\n## Key Files\n\n- `quality_gates.py` — existing pre-merge quality gates (extend, don't replace)\n- `quality_review.py` — existing syntax validation for core files\n- `api.py` — primary refactoring target (30K lines)\n- `tools.py` — second largest file (3,337 lines)\n","spec_html":"<div style=\"font-size:0.85rem\"><p style=\"color:#bbb;line-height:1.6;margin:0.4rem 0\"><h2 style=\"color:#4fc3f7;margin:1.5rem 0 0.6rem;font-size:1.2rem;font-weight:700\">Quest: Code Health</h2></p><p style=\"color:#bbb;line-height:1.6;margin:0.4rem 0\"><h3 style=\"color:#4fc3f7;margin:1.4rem 0 0.5rem;font-size:1.1rem;font-weight:700;border-bottom:2px solid rgba(79,195,247,0.3);padding-bottom:0.2rem\">Vision</h3></p><p style=\"color:#bbb;line-height:1.6;margin:0.4rem 0\">SciDEX grows fast — 367 Python files, 124K LOC, 30K-line god file, 48 duplicate<br>function definitions. This quest applies conservative, continuous pressure to improve<br>code quality without removing important functionality or destabilizing the system.</p><p style=\"color:#bbb;line-height:1.6;margin:0.4rem 0\"><strong style=\"color:#e0e0e0\">Principles:</strong>\n<li style=\"margin:0.15rem 0;color:#bbb\"><strong style=\"color:#e0e0e0\">Conservative first</strong> — never remove code that might be in use; archive, don&#x27;t delete</li>\n<li style=\"margin:0.15rem 0;color:#bbb\"><strong style=\"color:#e0e0e0\">Verify before acting</strong> — check git blame, imports, cron jobs, systemd before touching</li>\n<li style=\"margin:0.15rem 0;color:#bbb\"><strong style=\"color:#e0e0e0\">Test after every change</strong> — all pages return 200, services healthy, API responds</li>\n<li style=\"margin:0.15rem 0;color:#bbb\"><strong style=\"color:#e0e0e0\">Incremental</strong> — small, safe steps; never refactor everything at once</li>\n<li style=\"margin:0.15rem 0;color:#bbb\"><strong style=\"color:#e0e0e0\">Never contradict SciDEX goals</strong> — code health serves the mission, not the other way around</li></p><p style=\"color:#bbb;line-height:1.6;margin:0.4rem 0\"><h3 style=\"color:#4fc3f7;margin:1.4rem 0 0.5rem;font-size:1.1rem;font-weight:700;border-bottom:2px solid rgba(79,195,247,0.3);padding-bottom:0.2rem\">Current State (Baseline Metrics)</h3></p><p style=\"color:#bbb;line-height:1.6;margin:0.4rem 0\"><table style=\"width:100%;border-collapse:collapse;margin:0.5rem 0;background:#151525;border-radius:6px;overflow:hidden\"><thead><tr><th style=\"padding:0.3rem 0.6rem;border-bottom:2px solid rgba(79,195,247,0.3);color:#4fc3f7;font-size:0.8rem;text-align:left\">Metric</th><th style=\"padding:0.3rem 0.6rem;border-bottom:2px solid rgba(79,195,247,0.3);color:#4fc3f7;font-size:0.8rem;text-align:left\">Current</th><th style=\"padding:0.3rem 0.6rem;border-bottom:2px solid rgba(79,195,247,0.3);color:#4fc3f7;font-size:0.8rem;text-align:left\">Target</th></tr></thead><tbody><tr><td style=\"padding:0.3rem 0.6rem;border-bottom:1px solid rgba(255,255,255,0.05);color:#bbb;font-size:0.8rem\">Root-level Python files</td><td style=\"padding:0.3rem 0.6rem;border-bottom:1px solid rgba(255,255,255,0.05);color:#bbb;font-size:0.8rem\">305</td><td style=\"padding:0.3rem 0.6rem;border-bottom:1px solid rgba(255,255,255,0.05);color:#bbb;font-size:0.8rem\">&lt;80</td></tr><tr><td style=\"padding:0.3rem 0.6rem;border-bottom:1px solid rgba(255,255,255,0.05);color:#bbb;font-size:0.8rem\">api.py line count</td><td style=\"padding:0.3rem 0.6rem;border-bottom:1px solid rgba(255,255,255,0.05);color:#bbb;font-size:0.8rem\">30,283</td><td style=\"padding:0.3rem 0.6rem;border-bottom:1px solid rgba(255,255,255,0.05);color:#bbb;font-size:0.8rem\">&lt;5,000 (split into modules)</td></tr><tr><td style=\"padding:0.3rem 0.6rem;border-bottom:1px solid rgba(255,255,255,0.05);color:#bbb;font-size:0.8rem\">Duplicate get_db() definitions</td><td style=\"padding:0.3rem 0.6rem;border-bottom:1px solid rgba(255,255,255,0.05);color:#bbb;font-size:0.8rem\">48</td><td style=\"padding:0.3rem 0.6rem;border-bottom:1px solid rgba(255,255,255,0.05);color:#bbb;font-size:0.8rem\">1 (shared module)</td></tr><tr><td style=\"padding:0.3rem 0.6rem;border-bottom:1px solid rgba(255,255,255,0.05);color:#bbb;font-size:0.8rem\">Duplicate search_pubmed()</td><td style=\"padding:0.3rem 0.6rem;border-bottom:1px solid rgba(255,255,255,0.05);color:#bbb;font-size:0.8rem\">15</td><td style=\"padding:0.3rem 0.6rem;border-bottom:1px solid rgba(255,255,255,0.05);color:#bbb;font-size:0.8rem\">1</td></tr><tr><td style=\"padding:0.3rem 0.6rem;border-bottom:1px solid rgba(255,255,255,0.05);color:#bbb;font-size:0.8rem\">Duplicate extract_edges_from_abstract()</td><td style=\"padding:0.3rem 0.6rem;border-bottom:1px solid rgba(255,255,255,0.05);color:#bbb;font-size:0.8rem\">12</td><td style=\"padding:0.3rem 0.6rem;border-bottom:1px solid rgba(255,255,255,0.05);color:#bbb;font-size:0.8rem\">1</td></tr><tr><td style=\"padding:0.3rem 0.6rem;border-bottom:1px solid rgba(255,255,255,0.05);color:#bbb;font-size:0.8rem\">Version-suffixed dead code files</td><td style=\"padding:0.3rem 0.6rem;border-bottom:1px solid rgba(255,255,255,0.05);color:#bbb;font-size:0.8rem\">27+</td><td style=\"padding:0.3rem 0.6rem;border-bottom:1px solid rgba(255,255,255,0.05);color:#bbb;font-size:0.8rem\">0 (archived)</td></tr><tr><td style=\"padding:0.3rem 0.6rem;border-bottom:1px solid rgba(255,255,255,0.05);color:#bbb;font-size:0.8rem\">Migration number collisions</td><td style=\"padding:0.3rem 0.6rem;border-bottom:1px solid rgba(255,255,255,0.05);color:#bbb;font-size:0.8rem\">2</td><td style=\"padding:0.3rem 0.6rem;border-bottom:1px solid rgba(255,255,255,0.05);color:#bbb;font-size:0.8rem\">0</td></tr><tr><td style=\"padding:0.3rem 0.6rem;border-bottom:1px solid rgba(255,255,255,0.05);color:#bbb;font-size:0.8rem\">Linting config</td><td style=\"padding:0.3rem 0.6rem;border-bottom:1px solid rgba(255,255,255,0.05);color:#bbb;font-size:0.8rem\">None</td><td style=\"padding:0.3rem 0.6rem;border-bottom:1px solid rgba(255,255,255,0.05);color:#bbb;font-size:0.8rem\">ruff in pyproject.toml</td></tr><tr><td style=\"padding:0.3rem 0.6rem;border-bottom:1px solid rgba(255,255,255,0.05);color:#bbb;font-size:0.8rem\">Test files</td><td style=\"padding:0.3rem 0.6rem;border-bottom:1px solid rgba(255,255,255,0.05);color:#bbb;font-size:0.8rem\">7 (580 lines)</td><td style=\"padding:0.3rem 0.6rem;border-bottom:1px solid rgba(255,255,255,0.05);color:#bbb;font-size:0.8rem\">20+ (2K+ lines)</td></tr><tr><td style=\"padding:0.3rem 0.6rem;border-bottom:1px solid rgba(255,255,255,0.05);color:#bbb;font-size:0.8rem\">Files with raw sqlite3.connect()</td><td style=\"padding:0.3rem 0.6rem;border-bottom:1px solid rgba(255,255,255,0.05);color:#bbb;font-size:0.8rem\">287</td><td style=\"padding:0.3rem 0.6rem;border-bottom:1px solid rgba(255,255,255,0.05);color:#bbb;font-size:0.8rem\">&lt;50 (core scripts only)</td></tr></tbody></table>\n<h3 style=\"color:#4fc3f7;margin:1.4rem 0 0.5rem;font-size:1.1rem;font-weight:700;border-bottom:2px solid rgba(79,195,247,0.3);padding-bottom:0.2rem\">8 Tasks (Dependency Order)</h3></p><p style=\"color:#bbb;line-height:1.6;margin:0.4rem 0\"><pre style=\"background:#0a0a14;padding:0.8rem;border-radius:6px;border:1px solid rgba(79,195,247,0.15);color:#e0e0e0;font-size:0.8rem;overflow-x:auto;margin:0.5rem 0;line-height:1.5\"><code>Recurring Sweep ──&gt; (informs priorities for all below)\n\nFix Migrations (independent, quick win)\n\nAdd Linting (independent, infrastructure)\n\nArchive Dead Code ──&gt; Organize File Sprawl\n\nConsolidate DB Patterns ──┐\n                          ├──&gt; Break Apart api.py\nConsolidate Utility Fns ──┘</code></pre></p><p style=\"color:#bbb;line-height:1.6;margin:0.4rem 0\"><h3 style=\"color:#4fc3f7;margin:1.4rem 0 0.5rem;font-size:1.1rem;font-weight:700;border-bottom:2px solid rgba(79,195,247,0.3);padding-bottom:0.2rem\">Safety Protocol</h3></p><p style=\"color:#bbb;line-height:1.6;margin:0.4rem 0\">Every code health change MUST:</p><p style=\"color:#bbb;line-height:1.6;margin:0.4rem 0\"><li style=\"margin:0.15rem 0;color:#bbb\"><strong style=\"color:#e0e0e0\">Check references</strong> before removing/moving anything:</li>\n   <br><pre style=\"background:#0a0a14;padding:0.8rem;border-radius:6px;border:1px solid rgba(79,195,247,0.15);color:#e0e0e0;font-size:0.8rem;overflow-x:auto;margin:0.5rem 0;line-height:1.5\"><code># Is this file imported anywhere?\n   grep -r &quot;import filename&quot; --include=&quot;*.py&quot; .\n   grep -r &quot;from filename&quot; --include=&quot;*.py&quot; .\n   # Is it in a systemd service?\n   grep -r &quot;filename&quot; /etc/systemd/system/scidex-*.service\n   # Is it in a cron job?\n   crontab -l | grep filename</code></pre></p><p style=\"color:#bbb;line-height:1.6;margin:0.4rem 0\"><li style=\"margin:0.15rem 0;color:#bbb\"><strong style=\"color:#e0e0e0\">Test after changes</strong>:</li>\n   <br><pre style=\"background:#0a0a14;padding:0.8rem;border-radius:6px;border:1px solid rgba(79,195,247,0.15);color:#e0e0e0;font-size:0.8rem;overflow-x:auto;margin:0.5rem 0;line-height:1.5\"><code>for page in / /exchange /analyses/ /graph /gaps /senate /forge; do\n     code=$(curl -s -o /dev/null -w &#x27;%{http_code}&#x27; &quot;http://localhost:8000${page}&quot;)\n     echo &quot;${code} ${page}&quot;\n   done\n   curl -s http://localhost:8000/api/status | python3 -m json.tool</code></pre></p><p style=\"color:#bbb;line-height:1.6;margin:0.4rem 0\"><li style=\"margin:0.15rem 0;color:#bbb\"><strong style=\"color:#e0e0e0\">Commit atomically</strong> — one logical change per commit, easy to revert</li></p><p style=\"color:#bbb;line-height:1.6;margin:0.4rem 0\"><li style=\"margin:0.15rem 0;color:#bbb\"><strong style=\"color:#e0e0e0\">Keep archive/</strong> — moved files go to <code style=\"background:#1a1a2e;color:#ce93d8;padding:0.1rem 0.3rem;border-radius:3px;font-size:0.85em\">archive/</code> directory, not deleted</li></p><p style=\"color:#bbb;line-height:1.6;margin:0.4rem 0\"><h3 style=\"color:#4fc3f7;margin:1.4rem 0 0.5rem;font-size:1.1rem;font-weight:700;border-bottom:2px solid rgba(79,195,247,0.3);padding-bottom:0.2rem\">Key Files</h3></p><p style=\"color:#bbb;line-height:1.6;margin:0.4rem 0\"><ul style=\"padding-left:1.5rem;margin:0.4rem 0\"><li style=\"margin:0.15rem 0;color:#bbb\"><code style=\"background:#1a1a2e;color:#ce93d8;padding:0.1rem 0.3rem;border-radius:3px;font-size:0.85em\">quality_gates.py</code> — existing pre-merge quality gates (extend, don&#x27;t replace)</li>\n<li style=\"margin:0.15rem 0;color:#bbb\"><code style=\"background:#1a1a2e;color:#ce93d8;padding:0.1rem 0.3rem;border-radius:3px;font-size:0.85em\">quality_review.py</code> — existing syntax validation for core files</li>\n<li style=\"margin:0.15rem 0;color:#bbb\"><code style=\"background:#1a1a2e;color:#ce93d8;padding:0.1rem 0.3rem;border-radius:3px;font-size:0.85em\">api.py</code> — primary refactoring target (30K lines)</li>\n<li style=\"margin:0.15rem 0;color:#bbb\"><code style=\"background:#1a1a2e;color:#ce93d8;padding:0.1rem 0.3rem;border-radius:3px;font-size:0.85em\">tools.py</code> — second largest file (3,337 lines)</li>\n</ul></p></div>","spec_file":"quest_code_health.md"}