feat: deeper Wave 2 + observability dashboard
Wave 2 deeper ingestion: - 6 new Trusted Project State entries from design-level docs: p05: test rig architecture, CGH specification, procurement combos p06: force control architecture, control channels, calibration loop - Total state entries: ~23 (was ~17) Observability: - GET /admin/dashboard — one-shot system overview: memory counts by type/project/status, reinforced count, project state entry counts, recent interaction timestamp, extraction pipeline status. Replaces the need to query 4+ endpoints to understand system state. Harness: 17/18 (no regression from new state entries). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -866,6 +866,66 @@ def api_extract_batch(req: ExtractBatchRequest | None = None) -> dict:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@router.get("/admin/dashboard")
|
||||||
|
def api_dashboard() -> dict:
|
||||||
|
"""One-shot system observability dashboard.
|
||||||
|
|
||||||
|
Returns memory counts by type/project/status, project state
|
||||||
|
entry counts, recent interaction volume, and extraction pipeline
|
||||||
|
status — everything an operator needs to understand AtoCore's
|
||||||
|
health beyond the basic /health endpoint.
|
||||||
|
"""
|
||||||
|
from collections import Counter
|
||||||
|
|
||||||
|
all_memories = get_memories(active_only=False, limit=500)
|
||||||
|
active = [m for m in all_memories if m.status == "active"]
|
||||||
|
candidates = [m for m in all_memories if m.status == "candidate"]
|
||||||
|
|
||||||
|
type_counts = dict(Counter(m.memory_type for m in active))
|
||||||
|
project_counts = dict(Counter(m.project or "(none)" for m in active))
|
||||||
|
reinforced = [m for m in active if m.reference_count > 0]
|
||||||
|
|
||||||
|
interactions = list_interactions(limit=1)
|
||||||
|
recent_interaction = interactions[0].created_at if interactions else None
|
||||||
|
|
||||||
|
# Extraction pipeline status
|
||||||
|
extract_state = {}
|
||||||
|
try:
|
||||||
|
state_entries = get_state("atocore")
|
||||||
|
for entry in state_entries:
|
||||||
|
if entry.category == "status" and entry.key == "last_extract_batch_run":
|
||||||
|
extract_state["last_run"] = entry.value
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Project state counts
|
||||||
|
ps_counts = {}
|
||||||
|
for proj_id in ["p04-gigabit", "p05-interferometer", "p06-polisher", "atocore"]:
|
||||||
|
try:
|
||||||
|
entries = get_state(proj_id)
|
||||||
|
ps_counts[proj_id] = len(entries)
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
|
return {
|
||||||
|
"memories": {
|
||||||
|
"active": len(active),
|
||||||
|
"candidates": len(candidates),
|
||||||
|
"by_type": type_counts,
|
||||||
|
"by_project": project_counts,
|
||||||
|
"reinforced": len(reinforced),
|
||||||
|
},
|
||||||
|
"project_state": {
|
||||||
|
"counts": ps_counts,
|
||||||
|
"total": sum(ps_counts.values()),
|
||||||
|
},
|
||||||
|
"interactions": {
|
||||||
|
"most_recent": recent_interaction,
|
||||||
|
},
|
||||||
|
"extraction_pipeline": extract_state,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@router.get("/admin/backup/{stamp}/validate")
|
@router.get("/admin/backup/{stamp}/validate")
|
||||||
def api_validate_backup(stamp: str) -> dict:
|
def api_validate_backup(stamp: str) -> dict:
|
||||||
"""Validate that a previously created backup is structurally usable."""
|
"""Validate that a previously created backup is structurally usable."""
|
||||||
|
|||||||
Reference in New Issue
Block a user