Remediates the two blocking findings in review #522 on PR #849.
F1 — the session filter dimension was dead end to end. No source could
produce an event carrying a session identifier, so filter_events dropped
every event whenever session was supplied and the API answered with a
green, empty page. An empty result reads to an operator as "no such
session activity", which is a stronger and false claim.
Each source now declares which filter dimensions its records can actually
carry. The control-plane events table is (event_id, work_item_id,
event_type, message, created_at) and records no session, so that source
declares the session dimension unsupported rather than pretending to
answer it; the dead read of a non-existent session_id column is removed.
A CTH handoff comment declares its own Session field, so the handoff
adapter populates session_id from that declared field — authoritative
source data, never inferred from an actor, work item, or message text.
When no source that ran can carry a requested dimension, load_timeline
refuses with ok=false and a structured error naming the unsupported
filters and the per-source reason, and the route answers 422. A source
that can answer the dimension and simply matched nothing still returns
200 with an honest empty page. Ordering, pagination, and the issue/PR
filters are unchanged.
F2 — evidence_refs bypassed redaction and could emit a credential
verbatim. proof and decision were passed to _extract_evidence_refs before
redaction, and the SHA pattern matched any 7-40 character lowercase hex
run, which is exactly the shape of a Gitea access token.
Redaction now runs first and every derived value is taken from the
redacted text. A commit reference is recognised only where the source
text declares one (commit, head, base, sha, ...), so an undeclared hex
run is never lifted out of prose into a structured field; this also drops
the ordinary-word noise the reviewer noted. Every reference is then
independently revalidated against an allowed shape and a second redaction
pass immediately before serialization, failing closed by dropping
anything unproven and flagging the event sensitive. Actor is redacted for
the same reason, and a secret-shaped session value is dropped rather than
emitted. Legitimate issue, PR, short-SHA and full 40-character SHA
references stay usable.
Tests: 16 added. Session filtering is now driven through the CTH adapter
and the composed load_timeline/API path rather than a hand-built
WorkflowEvent, covering a match, an honest empty result, pagination and
ordering under the filter, the 422 refusal, and the per-source support
declaration. Redaction coverage asserts a synthetic 40-character hex
value (not a real credential) appears nowhere in the complete serialized
payload including evidence_refs, that the independent revalidation drops
unproven references, and that legitimate references still resolve.
pytest tests/test_webui_timeline.py: 42 passed (was 26).
pytest -k webui: 340 passed, 270 subtests passed (was 324).
Full suite: 4607 passed, 12 failed, 6 skipped, 684 subtests passed — the
same 12 failures as the master baseline, none under webui/.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Phase 1 child of the Web Console epic #631. Adds a durable, versioned
WorkflowEvent schema with per-source adapters and a read-only query API so
operators can browse a unified timeline of workflow events, decisions, tool
calls, and handoffs instead of scattered evidence.
- webui/timeline.py (new): versioned WorkflowEvent schema; control-plane
event adapter and Gitea CTH handoff-comment adapter; read-only mode=ro
control-plane reader; conjunctive filter by issue/PR/session; stable
(timestamp, source_rank, event_key) ordering; bounded pagination;
fail-soft per-source status; redaction at the boundary, fail closed.
- webui/app.py: GET /api/v1/timeline read-only route with thread-scoped,
fail-soft handoff comment source.
- tests/test_webui_timeline.py (new): schema, adapters, redaction of
secret-like payloads, filter/sort/pagination, scoped CP reader,
fail-soft composition, and API integration.
- docs/webui-local-dev.md: timeline route and field-authority notes.
Read-only Phase 1; no mutation of historical events; no full chat replay;
no unredacted tool-argument storage.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Resolve conflict remediation for PR #818 (Closes#638) against master
caaae9b6. Two conflicts in webui/app.py, both resolved as unions since
the Phase 1 shell work (#638) and the merged master changes touch
disjoint concerns:
- Imports: keep the new webui.nav (NAV_GROUPS, STUB_PAGES) import from
#638 alongside master's expanded project_registry / project_views API
(ProjectRegistry, RegistryError, known_project_ids,
project_detail_to_dict, render_registry_error).
- Route table: keep master's read-only /api/console/security-model route
alongside #638's read-only Phase 1 stub routes (STUB_PAGES).
No behavior change beyond union; console stays read-only. docs/webui-local-dev.md
auto-merged. Full webui suite green (272 passed, 310 subtests).
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Introduce a single nav-config module (webui/nav.py) driving grouped
navigation across the epic #631 Phase 1 information architecture:
Health, Traffic, Runtime/Sessions, Projects, Inventory, Timeline,
Policy (placeholder), and Insights (placeholder). The shell header now
carries a read-only environment badge (local/remote from WEBUI_HOST), a
mode: read-only badge, and a Docs link. Home summarizes the console
purpose, lists the Phase 1 surfaces by group, and links the MVP legacy
pages.
Not-yet-implemented surfaces (/sessions, /inventory, /timeline,
/policy, /insights) resolve to graceful read-only stub pages rather than
404s; their backing views land in later child issues of #631 (inventory
surfaces backed by #636). Mutating methods on stub routes still fail
closed with read-only-mvp. No privileged action controls are added.
Adds tests/test_webui_shell.py covering nav groups, badge presence,
environment classification, docs link, stub routes (200 + read-only),
and home content. Updates docs/webui-local-dev.md with the new routes
and a Phase 1 shell section.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Adds `GET /api/v1/system/health`, a structured read-only health surface for
automated readiness checks, and keeps `/health` as the cheap liveness probe.
webui/system_health.py composes a DTO from fail-soft dependency probes: the
control-plane database, the local checkout, and — opt-in via `?deep=1` — live
Gitea reachability, each carrying status, reason, and probe latency. Required
probes drive readiness; the optional Gitea probe can only degrade overall
status, because local inventory stays serveable when the remote is
unreachable. A probe that did not run leaves readiness incomplete rather than
silently passing.
Read-only throughout: the control-plane database is opened through a `mode=ro`
URI because `ControlPlaneDB.__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.
No unproven claims: `stale_runtime.mutation_safe` is true only when the
runtime, checkout, and remote commits are all known and equal, and MCP
namespaces always report `unproven` because a web process cannot exercise the
IDE-managed client path (#543). Probe details are redacted at the browser
boundary — URLs lose userinfo and query strings, credential-shaped text is
masked.
`/health` is expanded additively: every MVP key is retained, plus `started_at`,
`uptime_seconds`, and a pointer to the versioned API. The versioned route
returns 503 when not ready so automation can branch on the status code alone.
Verified at master 9eb0f29: focused file 40 passed / 11 subtests; `-k "webui or
health"` 230 passed / 159 subtests; full suite 4358 passed with the 11
pre-existing master-drift failures unchanged from the clean-master baseline.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Evolve the MVP project registry (#427) into a versioned, fail-closed
project registry API for the console (Phase 1, read-only).
- Add schema version 2 with project `status`, per-step onboarding
`state`/`required`, optional redacted `last_seen_health`, and
`remote_name`. Version 1 files stay loadable and are normalized with
explicit defaults.
- Serve `/api/v1/projects` and `/api/v1/projects/{project_id}` with API
provenance (`api_version`, `schema_version`, `source`). `/api/projects`
is retained as an unversioned Phase 1 alias.
- Replace bare `ValueError` with `RegistryError`, carrying an operator
`remediation` and `field_path`; invalid registries fail closed as a
500 JSON payload or a dedicated HTML error page instead of a traceback.
- Reject credential-shaped keys before any DTO is built, reusing
`registry_safety.is_forbidden_key` as the single source of truth
shared with the worker registry (#798).
- Render HTML views from `project_to_dict`, so the console and the JSON
API cannot disagree about status or onboarding progress.
- Document the contract in docs/webui-project-registry-api.md.
Tests: registry load/validate (valid, missing project, schema
validation, credential rejection) and API route coverage.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Adds the durable architecture record epic #631 lacked: layer contract,
authority boundaries, the redaction boundary, /api/v1 versioning with a
compatibility rule for the existing unversioned MVP exports, a target page
map, per-child component ownership for all twenty children (#632-#651),
phase gates, and explicit forbidden paths.
Documentation only. No UI, API, or deployment change.
- docs/architecture/webui-control-plane-console-architecture-adr.md (new)
- docs/webui-local-dev.md: cross-link to the ADR
- tests/test_webui_architecture_docs.py: doc gate for the acceptance
criteria and the cross-link (12 cases)
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Add consolidated MVP route/read-only tests, path-filter helpers, and
scripts/test-webui plus scripts/ci-webui-check for Jenkins path-filtered
runs on PRs touching web UI surfaces.
Closes#436
Add bind-host assessment that refuses 0.0.0.0/:: without override,
warns on non-loopback binds, and documents internal-only MVP serving.
Health endpoint exposes deployment metadata; docs cover Access/VPN/WARP
and runtime env assumptions without embedding secrets in the client.
Closes#435
Adds read-only /runtime and /api/runtime routes showing active profile,
identity, config model, git sync vs remote master, shell health,
workflow/schema hashes, and stale-runtime warnings with #420 guidance.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Adds read-only /leases and /api/leases routes for issue claim inventory,
reviewer PR lease comments, duplicate PR/branch warnings, and local issue
lock visibility without acquire/release mutations.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Adds read-only /worktrees and /api/worktrees routes that scan branches/
directories, classify worktree state, flag missing preserved worktrees from
the issue lock, and surface the canonical cleanup prompt without deletion.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Expose /audit and /api/audit for local validator previews using
final_report_validator and review schema checks. Operators can paste
reports, auto-detect task kind, and get structured findings with
suggested next prompts and issue-comment drafts.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Adds read-only /queue and /api/queue routes that load open PRs and issues
from the default registry project via gitea_auth, surface pagination proof,
and classify items with claimed/blocked/in-review/duplicate badges.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Expose short copy/paste operator prompts on /prompts derived from canonical
workflow files with workflow path and SHA-256 hash. Adds JSON export at
/api/prompts, copy buttons, and tests.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Starlette read-only MVP with shared layout, /health JSON liveness, and
route stubs for projects, prompts, runtime, audit, worktrees, and leases.
Includes scripts/run-webui, docs/webui-local-dev.md, and tests.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>