> ## 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:
> S1, S4 (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.
Task ID: eb8867b4-e8ed-4d36-82e1-3535919bd1e6
Type: Recurring (every 6h)
Layer: Senate
Script: scripts/garden_health_maintenance.py
Maintain the health of SciDEX's knowledge artifacts by running six maintenance checks every 6 hours, logging metrics, and proposing governance actions for degraded artifacts.
quality_verified=0 for 3+ days and low score → deprecation proposedgarden_health_log each cycleknowledge_gaps — stale gap detectionhypotheses — quality enforcement, citation integritydedup_recommendations — dedup auto-approvaluniversal_artifacts — orphan cleanupgovernance_decisions — proposal store (also dedup-pruned each cycle)garden_health_log — metrics outputartifact_links, knowledge_edges — orphan detectionpapers — citation validity checkAgent: sonnet-4.6 Branch: resume-20260412_011041_worktree Commit: 1cfc044f
scripts/garden_health_maintenance.py with full 6-step pipelineAgent: sonnet-4.6 Branch: senate-run44-clean
Problem found: governance_decisions table has no UNIQUE constraint on (content_id, decision_type). The propose_governance_decision function relied on a constraint that doesn't exist, so every 6h cycle created new duplicate pending decisions. After 8 cycles: 1500 pending decisions with 7-8 copies per artifact.
Fixes applied:
propose_governance_decision — added explicit SELECT check for existing pending decision before INSERT, preventing future accumulationprune_duplicate_governance_decisions() (Step 0) — runs first each cycle to clean up any stragglers; deletes all but newest pending decision per (content_id, decision_type)--gov-dedup CLI flag for standalone invocationRun results:
Agent: minimax:57 Branch: task-810043b5-27ba-4055-8130-c640ed848400
Results:
Agent: sonnet-4.6:72 Branch: senate/garden-health-run4
Results:
Agent: sonnet-4.6:73 Branch: push-dedup-run10
Results:
Agent: sonnet-4.6:73 Branch: wiki-edit-market-c6bd6dc1
Results:
Agent: sonnet-4.6 Branch: task-eb8867b4-garden-health
Results:
Agent: sonnet-4.6:73 Branch: orchestra/task/57531385-1f09-4e0d-ad35-fc45a509b0ee
Results:
Agent: sonnet-4.6:71 Branch: orchestra/task/eb8867b4-e8ed-4d36-82e1-3535919bd1e6
Results:
Agent: sonnet-4.6 Branch: orchestra/task/6ae1c418-6f67-436a-a504-8072f9cacad0
Results:
Agent: sonnet-4.6 Branch: senate/garden-run15-clean
Results:
Agent: sonnet-4.6 Branch: orchestra/task/46ae57a3-2883-4a36-a888-fc39d0812b27
Results:
Agent: sonnet-4.6:41 Branch: task-b342c414-speclog-final Commit: 303cd9928
Bug found and fixed: auto_approve_dedup() handled merge_wiki_pages and merge_hypotheses but not merge_gaps. This caused high-confidence gap dedup approvals to be silently skipped (status set to 'approved' but no actual merge executed). A previous cycle had approved 14 merge_gaps records with no execution.
Fixes applied:
merge_gaps handler: resolves absorbed gaps (status='resolved', parent_gap_id=survivor) and marks their universal_artifact entries as merged.merge_gaps records, so previously missed merges get executed in the next cycle without requiring a DB reset.with_retry() helper with exponential backoff (up to 6 attempts) for write operations that hit DB lock errors from the concurrent API process.PRAGMA busy_timeout=60000 to write connections.Results:
Agent: minimax:63 Branch: orchestra/task/eb8867b4-knowledge-garden-automated-pruning-dedup
Problem found: The script was deprecated in commit b4a034242 ("Consolidate file naming: drop _pg suffix, deprecate 128 SQLite scripts") because it was SQLite-only and PG became the only backend.
Fixes applied:
scripts/garden_health_maintenance.py as PostgreSQL-compatible version? (SQLite) to %s (PostgreSQL)get_connection() from scidex.core.db_connect for database accessenforce_quality(): compared datetime object with string cutoffcheck_citation_integrity(): PostgreSQL JSONB returns parsed list, not stringCOUNT(*) column access: use fetchone()["cnt"] instead of fetchone()[0] for dict_rowevidence_for empty string comparison in PostgreSQL: used evidence_for::text != '' instead of evidence_for != ''garden_health_log sequence sync issue: nextval was returning existing IDsResults:
{
"completion_shas": [
"9c8155b9cc8bad0e6ecc31739abfc7b0815ebef3",
"958aaa4e148e73d28a7175d3bc9d5a51ce1101b4",
"ed8f7a23bfbe5ae24ea53ce2693eae489ceef32c",
"a8e80d4e1f673e8e8d792f1933ec6ec972b9c577",
"37204ecaa42af6f51b1990b99da84e4da57ceb71",
"823c946e1b36522dece66c463abe6eb3c92aec35",
"c6f57266646ffa304caa222ef6b767afe1e50ddc",
"d49500732ad661118aa257833b765f15c5cd188a",
"5e0f614a8fedf620ccb0343670d519b1dc2d6709",
"d0650e2d8739d297db2909b51724a29c2b5144fb",
"1cfc044f0f0ce5ff7d92e321521e0756b8a08f81",
"ec9fdd5ea9fe1172e6fb5cfe0c4814419477e776"
],
"completion_shas_checked_at": "2026-04-13T05:46:31.518343+00:00",
"completion_shas_missing": [
"7b7b7aee9b77929dc0779616e40f79f90a9b063c",
"5ff71ffb100bb3960faedd3f14e5a44db13ca17b",
"90afcda8cc68f6c29f698edb367e7f2206083da8",
"ec6ae39fc7a07a9516659bc9cf284412fc263a37",
"dd0d9e00e095e57d0775aa20ffd447754237a2c9",
"4bc7bce82e225af52424f628ea48e37104e160bc",
"ba86e66da2e2c87935916866d3ccf6928dce25c7",
"f8ca93abeabb421e1751d9467c7a1fa6c88ed1f2",
"0baa1531e9713155205bca7dff39c159b44392fa",
"a973e867ec7dca8178ff8fadba17f31926e0671c",
"adf07ad8ea7670302ffb3a1fefae3650eaaf9f5d",
"31ad63cd33bb3ff4dbfac34b4b97bbdf9f184069",
"9faf8768d8321d0523b21231fbabf4ea90b5a7e9",
"64963293f0e2d39063eb1db12b4cf04074855fcd",
"d0dfddafa166b25896c1e16629109dd1a5b8fb5a",
"08dff830b1a2e2928aa3024bca4ca5e05b053ca1",
"30a1fd95b4209edb64afb2700d482194f6c4f29e",
"b7244fd0c799e170716f814d59f2fafd37352cbb",
"962363cd0b1e46c69371c61d991e2268729b4c0d",
"f011fc4f77a0e72d34a2535949720de2b4b5ba91",
"e3392b0fbbafea0f0a85017b86820fa5c94a5f61",
"a74d33331d30c0f6ad2482501b6341b7141c66cb",
"4121d49a678ac4a2077f7372928d4646410db52f",
"388091564b0e945720d9a1e8dd167fb2cfe7664d",
"86d4b89f767a4440ffcac21825df128fac640135",
"f7e45f8afeec2dead8cebf57cec33e8a6292269f",
"75adaf99aef4c78f1249fee42e128b0db4a1e93d",
"416ab8a27de4b6e7715612f128fd21ee6d54cc4e",
"ad7a77166c69ab5c4db9b066126e941e8caf96b8",
"59db4a7329ba903cddac21dba43a75fd3f3f78cb",
"3fd8f38abe53cb92ef283ba851da8fe6b53d39a1",
"21ba4fce858b20b8774c6359def9e83c7e04cd0f"
],
"requirements": {
"coding": 7,
"reasoning": 7,
"safety": 8
}
}