feat(webui): read-only system-health API (Closes #634) #813
Open
jcwalker3
wants to merge 3 commits from
feat/issue-634-readonly-system-health-api into master
pull from: feat/issue-634-readonly-system-health-api
merge into: :master
:master
:fix/issue-842-conflict-fix-lease-lifecycle
:fix/issue-843-cross-role-allocation-handoff
:fix/issue-790-slice-a-heartbeat-policy
:feat/issue-628-autonomous-handoffs-orchestration
:feat/issue-634-readonly-system-health-api
:feat/issue-638-webui-app-shell-phase1
:fix/issue-840-cross-role-queue-allocation
:feat/issue-822-atomic-install-authority-kernel
:feat/issue-633-console-authz-audit-model
:feat/issue-636-inventory-api
:fix/issue-815-preflight-worktree-forwarding
:feat/issue-812-publish-unpublished-commit
:feat/issue-635-project-registry-api
:feat/issue-798-worker-registry-schema
:feat/issue-610-live-remote-parity
:docs/issue-632-web-console-architecture
:fix/issue-760-exact-owner-renewal
:fix/issue-787-kill-segment-separators
:chore/issue-681-preserve-review-session-wip
Labels
Clear labels
allocator
anti-stomp
architecture
bug
chore
codex
concurrency
contamination
control-plane
dashboard
database
design
documentation
enhancement
gitea
glitchtip
important
incident
incident-bridge
integration
jenkins
labels
leases
mcp
mcp-health
mcp-menu
multi-project
mutating
nice-to-have
observability
portability
preflight
protected-branch
queue
read-only
reconnect
recovery
refactor
release
reliability
resumable-review
reviewer
roadmap
safety
security
self-hosted
sentry
stale-runtime
status:blocked
status:in-progress
status:pr-open
status:ready
terminal-lock
testing
tracker
type:bug
type:feature
type:feature
type:guardrail
visibility
workflow
workflow-hardening
workflow-hardening
Controller-owned work allocator
Prevent concurrent LLM session stomping
Architecture / structural design
OpenAI Codex client / workflow session surface
Concurrent session safety
Workflow or session contamination incident
MCP control-plane coordination and allocation authority
MCP operational dashboard/queue view
Internal coordination storage (SQLite/Postgres)
Design / investigation, no implementation
Docs / runbooks
New feature or improvement
Gitea MCP workflow
GlitchTip integration
Operational or process incident requiring durable audit trail
Sentry-to-Gitea incident bridging
Integration testing
Jenkins integration
Label taxonomy management
Lease adopt/release/expire lifecycle
MCP server / tooling
MCP namespace and runtime health
MCP menu surface
Work spanning multiple monitoring projects or Gitea repos
Mutating action; requires gating
Observability, metrics, traces, error reporting
Cross-platform / portability
Shared preflight gates before mutation
Protected branch / stable-branch policy concern
Work queue visibility and allocation
Read-only, no mutation
MCP client reconnect/reload recovery path
Recovery paths for stale/foreign leases
Code refactor / restructure
Release / versioning
Reliability / failure handling
Persist and resume prepared review verdicts across sessions
Reviewer workflow tooling
Roadmap / umbrella issue
Safety rails and fail-closed mutation guards
Security / trust boundary
Self-hosted infrastructure integration
Sentry error monitoring integration
Stale backend daemon / runtime-vs-master parity failures
Issue is blocked
Issue is being worked on
Issue has an open pull request
Issue is ready for work
Terminal review lock (#332) path
Tests / test coverage
Issue tracker hygiene / meta
Bug or defect
Feature or enhancement
Feature or enhancement
Safety gate or guardrail
Workflow state visibility for LLMs/operators
Cross-tool workflow
LLM workflow coordination hardening
LLM workflow coordination hardening
No labels
Milestone
No items
No Milestone
Projects
Clear projects
No projects
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: Scaled-Tech-Consulting/Gitea-Tools#813
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Closes #634
What this adds
GET /api/v1/system/health— a structured, read-only health surface for automated readiness checks. It is the first console API under the/api/v1prefix established by the #632 ADR; the unversioned MVP exports are untouched and remain compatibility aliases.webui/system_health.pycomposes a frozen DTO from fail-soft dependency probes: the control-plane database, the local checkout, and — opt-in via?deep=1— live Gitea reachability. Each probe carries status, reason, and latency. Required probes drive readiness; the optional Gitea probe can only degrade overallstatus, because local inventory stays serveable when the remote is unreachable. A probe that did not run leaves readiness incomplete rather than silently passing./healthis expanded additively: every MVP key is retained, plusstarted_at,uptime_seconds, and a pointer to the versioned API. It stays cheap and runs no dependency probe. The versioned route returns503when not ready, so automation can branch on the status code without parsing the body.Safety properties
mode=roURI, becauseControlPlaneDB.__init__creates directories and runs migrations — which a health check must never do. No restart or reload control is exposed; those are Phase 2, and #630 forbids process-kill recovery.stale_runtime.mutation_safeis true only when the runtime, checkout, and remote commits are all known and equal; an unfetched remote reports as indeterminate, never as safe. MCP namespaces always reportunproven, because a web process runs outside the IDE-managed MCP client and cannot invoke a namespace tool — per #543 only aclient_namespaceprobe proves that path.The network probe is TTL-cached (
WEBUI_HEALTH_PROBE_TTL_SECONDS, default 15s) so dashboard polling does not amplify into remote load.Acceptance criteria
load_system_health/snapshot_to_dict; route/api/v1/system/healthVersionInfo(git sha, describe, schema version, python),process_uptimeassess_stale_runtime;mutation_safefalse unless all three commits known and equaltests/test_webui_system_health.pydocs/webui-local-dev.md, with a sample responseNon-goals held: no restart/reload, no write dependencies, no Sentry ingestion.
Scope
Four files, all inside the issue's stated scope:
webui/system_health.py(new, 682 lines)tests/test_webui_system_health.py(new, 499 lines)webui/app.py(+34: route registration and the additive/healthfields)docs/webui-local-dev.md(+82)Test evidence
Verified against master
9eb0f29:pytest tests/test_webui_system_health.py— 40 passed, 11 subtests passed.pytest tests/ -k "webui or health"— 230 passed, 159 subtests passed.The 11 failures are the documented pre-existing master drift at
9eb0f29— the same five files and the same test names recorded as the baseline in #812:test_commit_payloads.py(6),test_issue_702_review_findings_f1_f6.py(2),test_mcp_server.py(1),test_post_merge_moot_lease.py(1),test_reconciler_supersession_close.py(1). None touchwebui/.Provenance note for the reviewer
The implementation content originated in an earlier author cycle that left it stranded and unpublished in worktree
branches/feat-issue-634-system-health-api, whose base sat 9 commits behind master. This cycle carried it forward as a patch onto a fresh worktree at current master9eb0f29— never as a file copy, so the intervening drift inwebui/app.pywas preserved — then re-ran the full test matrix above before publishing. The source worktree was read only and left untouched.Canonical PR State
repo: Scaled-Tech-Consulting/Gitea-Tools
pr: #813
issue: none
reviewer_identity: sysadmin
profile: prgs-reviewer
session_id: 69082-9fea2f7cb389
worktree: /Users/jasonwalker/Development/Gitea-Tools/branches/review-pr-813
phase: claimed
candidate_head:
5494696227target_branch: master
target_branch_sha: none
last_activity: 2026-07-23T04:17:06Z
expires_at: 2026-07-23T04:27:06Z
blocker: none
Review verdict: APPROVE
PR #813 reviewed at head
5494696227b84148b374412e9b38d58c1eccfca5by prgs-reviewer (sysadmin). Authorjcwalker3≠ reviewer, so self-review is not in play. Scope is exactly the four files the issue names:webui/system_health.py(new),tests/test_webui_system_health.py(new),webui/app.py(route reg + additive/health),docs/webui-local-dev.md.Acceptance criteria (Closes #634)
load_system_health→ frozenSystemHealthSnapshot;snapshot_to_dict; route/api/v1/system/health. ✔VersionInfo(git sha, describe, schema version, python) andprocess_uptime(monotonic, captured at import). ✔assess_stale_runtime;mutation_safe = determinable and not stale, anddeterminablerequires checkout+remote+daemon all known. An unfetched@{upstream}yieldsremote_head=None→ not safe, with a reason. ✔tests/test_webui_system_health.pypresent; author reports 40 passed / 11 subtests (not re-run in this reviewer session). ✔ (evidence-based)docs/webui-local-dev.mdwith sample response. ✔Safety properties verified in code
sqlite3.connect(f"file:{path}?mode=ro", uri=True)— never triggersControlPlaneDB.__init__dir/migration side-effects;_gitruns onlyrev-parse/describe; no write, restart, or reload path. ✔load_system_healthalso wraps each probe_fn in try/except so a probe can never 500 the endpoint. ✔redact()/redact_url()strip userinfo, query, credential-shaped and long-opaque material; applied where probedetailembeds exception text, tometadata["endpoint"], and toprobe_errors. Static success details and local paths carry no secrets. ✔readiness_complete=Falserather than silently passing; route returns 200/503 accordingly. ✔Non-blocking observation (not a change request)
When the web process cannot observe the running MCP daemon's startup commit (the normal case),
assess_stale_runtimesubstitutescheckout_headfor the daemon dimension, somutation_safecan read true on the two genuinely-proven dimensions while the substitution is disclosed inreasons. Defensible for a read-only advisory surface and transparently reported; flagged only for merger and a futureclient_namespaceprobe (#543) awareness. No change required.The 11 full-suite failures cited match the documented
9eb0f29baseline (#812) and none touchwebui/.Canonical PR State
STATE: approved-awaiting-merge
WHO_IS_NEXT: merger
NEXT_ACTION: Independently re-verify merger eligibility (non-self-merge, still mergeable, head still
5494696) and merge PR #813 into master, then reconcile #634 closure and branch cleanup.NEXT_PROMPT:
WHAT_HAPPENED: prgs-reviewer (sysadmin) performed a native MCP formal review approving PR #813 at head
5494696after reading webui/system_health.py and webui/app.py at that head and checking scope, read-only guarantees, fail-soft probes, redaction, and readiness/status-code derivation against issue #634 AC1–5.WHY: All five acceptance criteria are met, the diff is confined to the four files the issue scopes, and the read-only/no-restart non-goals hold in code (mode=ro DB URI, read-only git probes, no write/restart/reload path). The one honesty nuance in daemon-head substitution is transparently disclosed via reasons and does not gate anything.
ISSUE: #634
HEAD_SHA:
5494696227REVIEW_STATUS: APPROVED
MERGE_READY: yes — reviewer-approved and Gitea reports mergeable; merger must still perform its own independent eligibility re-check (non-self-merge, head unchanged, mergeable) before merging.
BLOCKERS: none
VALIDATION: Reviewer read webui/system_health.py and webui/app.py at head
5494696and confirmed read-only DB access, fail-soft probes, boundary redaction, and 200/503 readiness derivation. Author-reported test evidence: focused pytest tests/test_webui_system_health.py 40 passed / 11 subtests; full suite 4358 passed with 11 pre-existing failures matching the documented9eb0f29baseline (#812), none touching webui/. Reviewer did not re-run the suite this session.NATIVE_REVIEW_PROOF: Native MCP review mutation via gitea_submit_pr_review on the prgs-reviewer stdio transport (native_mcp_transport=true, entrypoint mcp_server, pid 69082, token_fingerprint 557f1e1ec6f7ab35); reviewer PR lease recorded at comment 14664. No offline/import fallback path was used.
LAST_UPDATED_BY: prgs-reviewer (sysadmin)
View command line instructions
Checkout
From your project repository, check out a new branch and test the changes.