Skip to content

feat(tui): PROOF9 obligations panel in TUI dashboard - #460

Merged
frankbria merged 3 commits into
mainfrom
feat/tui-proof-panel-457
Mar 20, 2026
Merged

feat(tui): PROOF9 obligations panel in TUI dashboard#460
frankbria merged 3 commits into
mainfrom
feat/tui-proof-panel-457

Conversation

@frankbria

@frankbria frankbria commented Mar 20, 2026

Copy link
Copy Markdown
Owner

Summary

Closes #457.

Adds a ProofPanel to the CodeFRAME TUI dashboard, giving users visibility into PROOF9 obligations without leaving the terminal.

Changes

data_service.py

  • DashboardData gains 3 new fields: open_requirements, expiring_waivers, open_obligation_count
  • load_dashboard_data fetches proof data in a new read-only try/except block (no DB mutations — explicitly avoids check_expired_waivers)

app.py

  • #proof-panel widget (amber $warning border) added below #blocker-panel in the right column
  • _update_proof_panel() renders:
    • Empty state: "No open obligations"
    • Expiry warnings: ⚠ REQ-001: waiver expires in 3d — ...
    • Open requirements: REQ-002 high Auth token not validated | UNIT ⏳ SEC ✅
    • Gate icons: ✅ satisfied / ❌ failed / ⏳ pending
  • StatusBar shows N open obligations badge when count > 0

Test plan

  • 8 new tests in tests/core/test_tui_dashboard.py — all passing
  • All 19 dashboard tests passing (8 new + 11 existing)
  • ruff check clean
  • TUI renders correctly — empty state, expiring waivers, open requirements

Summary by CodeRabbit

  • New Features
    • Added a Proof panel showing open obligations, expiring waivers with days-until-expiry, and open requirements with severity indicators; status bar now displays an open obligations count and the panel shows a clear empty-state message when none exist.
  • Tests
    • Added tests for proof data loading and expiry filtering, status bar count, panel UI mounting, and empty-state behavior.

Add ProofPanel to the Textual dashboard showing open PROOF9 requirements,
gate results, waiver expiry warnings, and status bar badge.

Changes:
- data_service.py: DashboardData gains open_requirements, expiring_waivers,
  open_obligation_count; load_dashboard_data fetches them read-only from ledger
- app.py: #proof-panel widget (amber border) below #blocker-panel;
  _update_proof_panel() renders requirements with gate status icons (✅❌⏳);
  StatusBar shows "N open obligations" badge when count > 0
- tests: 8 new tests (5 data service + 3 widget) covering empty state,
  open requirements, expiring waivers, exclusion of far-future waivers,
  panel mount, and status bar badge
@coderabbitai

coderabbitai Bot commented Mar 20, 2026

Copy link
Copy Markdown
Contributor

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 457cc881-0fa0-4be6-973d-153759394d54

📥 Commits

Reviewing files that changed from the base of the PR and between bc7af40 and ef7b173.

📒 Files selected for processing (2)
  • codeframe/tui/data_service.py
  • tests/core/test_tui_dashboard.py
🚧 Files skipped from review as they are similar to previous changes (2)
  • codeframe/tui/data_service.py
  • tests/core/test_tui_dashboard.py

Walkthrough

Adds PROOF9 data and UI: DashboardData gains open requirements, expiring waivers, and open obligation count; data_service loads and filters proof data; TUI renders a new Proof panel (#proof-panel / #proof-log) and updates status bar with obligation count; tests added for data and UI behavior.

Changes

Cohort / File(s) Summary
TUI App / UI
codeframe/tui/app.py
Added #proof-panel with #proof-log RichLog; implemented _update_proof_panel() to render expiring waivers (days-until-expiry), open requirements (severity-colored, obligation icons), and show "No open obligations" when empty. Updated _refresh_data() to call _update_proof_panel(). Introduced _SEVERITY_COLORS and _OBLIGATION_ICONS. StatusBar now shows open obligation count when >0.
Data Service / Model
codeframe/tui/data_service.py
Extended DashboardData with open_requirements, expiring_waivers, and open_obligation_count. load_dashboard_data() fetches OPEN and WAIVED requirements from the proof ledger, computes near-term waiver expiries (<=7 days from date.today()), sets counts, and assigns proof-related error text if the proof load fails and no prior error existed.
Tests
tests/core/test_tui_dashboard.py
Added tests asserting DashboardData defaults for new fields, that OPEN requirements populate open_requirements and increment open_obligation_count, WAIVED requirements are filtered by 7-day expiry, graceful behavior when proof tables are missing, Proof panel mounting and empty-state message in #proof-log, and StatusBar update contains an obligation label.

Sequence Diagram

sequenceDiagram
    participant App as TUI App
    participant DataSvc as Data Service
    participant Ledger as Proof Ledger

    App->>DataSvc: _refresh_data()
    DataSvc->>Ledger: list_requirements(status=OPEN)
    Ledger-->>DataSvc: open_requirements[]
    DataSvc->>Ledger: list_requirements(status=WAIVED)
    Ledger-->>DataSvc: waived_requirements[]
    DataSvc->>DataSvc: filter waivers (expires within 7 days)
    DataSvc-->>App: DashboardData(with open_requirements, expiring_waivers, open_obligation_count)
    App->>App: _update_proof_panel()
    App->>App: render to `#proof-log` and update StatusBar
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Poem

🐇 I hopped to the dashboard, bright and keen,
New proof-panel lights where gaps had been.
Waivers warned, requirements in view,
Counts that tally — two, or maybe few.
I nibble bugs and cheer the new scene.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 72.22% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat(tui): PROOF9 obligations panel in TUI dashboard' directly and clearly describes the main change—adding a PROOF9 obligations panel to the TUI dashboard.
Linked Issues check ✅ Passed All primary objectives from issue #457 are met: open requirements and waiver counts are fetched and stored in DashboardData; the ProofPanel displays requirements with gate status icons; waiver expiry warnings show for items expiring within 7 days; status bar shows obligation count when > 0; empty state displays 'No open obligations'; and tests cover core behaviors and edge cases.
Out of Scope Changes check ✅ Passed All changes in app.py, data_service.py, and test files are directly scoped to implementing the proof panel feature described in issue #457; no unrelated modifications are present.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/tui-proof-panel-457

Comment @coderabbitai help to get the list of available commands and usage tips.

@claude

claude Bot commented Mar 20, 2026

Copy link
Copy Markdown

Code Review: feat(tui): PROOF9 obligations panel in TUI dashboard

Overall this is a well-scoped, architecturally sound addition. The change stays correctly within the TUI layer, calls core/proof/ledger.py with no FastAPI or server dependency, and follows the established defensive try/except pattern used by the other dashboard panels. The test suite covers the main paths well.


Issues to address before merge

1. from datetime import date inside a render loop (app.py)

The import is inside the for req in data.expiring_waivers: loop body. Python's import cache means this won't cause repeated module loads at runtime, but it's a PEP 8 violation and a code smell. Move it to the top of app.py:

# app.py top-level imports
from datetime import date

2. Semantic mismatch: open_obligation_count vs. len(open_reqs)

The field is named open_obligation_count but is set to len(open_reqs) — which counts requirements, not obligations (a requirement can have multiple gate obligations). The status bar badge says "X open obligations" but the panel lists requirements. Either:

  • Rename the field to open_requirement_count and update the status bar label, or
  • Set the count to sum(len(r.obligations) for r in open_reqs) to match the name

Whichever you choose, the field name and label should be consistent.

3. Negative/zero day display for expired waivers

_update_proof_panel recomputes date.today() at render time. If the dashboard is left open and a waiver's expiry date passes, the rendered string will show expires in 0d or expires in -1d. A simple clamp or label swap prevents a confusing display:

days = (req.waiver.expires - date.today()).days
label = f"expires in {days}d" if days > 0 else "EXPIRED"

Note: since check_expired_waivers isn't called in this path (correct — the dashboard should not mutate state), a lapsed waiver will remain in expiring_waivers until something else triggers that cleanup. Clamping the display handles the edge case gracefully.


Minor / nice-to-have

4. Missing test: waiver with expires=None

Waiver.expires is Optional[date]. The guard in load_dashboard_data handles this correctly, but there's no test confirming that a perpetual waiver (no expiry) is properly excluded from expiring_waivers. Worth adding a quick case.

5. Unused GlitchType import in tests

GlitchType is imported in test_load_with_open_requirements but not used. Minor cleanup.

6. Right-column density at small terminal heights

Three stacked panels in the right column (event log 2fr + blockers 1fr + proof 1fr) will be tight at 24–30 row terminals. Not a blocker, but consider auto-collapsing the proof panel when open_obligation_count == 0 as a follow-up.


What's good

  • Architecture compliance: TUI layer → core, no FastAPI, no mutation from dashboard read path
  • Graceful degradation: proof block failure won't crash the dashboard
  • _SEVERITY_COLORS and _OBLIGATION_ICONS as class-level dicts avoids per-render allocation
  • Proof imports inside try block prevent import-time failures from a broken proof subsystem
  • Good test boundary coverage for the 7-day threshold (3 days in vs. 30 days out)

Items 1–3 are the ones worth fixing before merge. Items 4–6 can be follow-ups.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
codeframe/tui/app.py (1)

107-112: ⚠️ Potential issue | 🟠 Major

Proof panel is not collapsible yet (objective gap).

The panel is always mounted/visible, and there is no collapse toggle state or action bound for it. This misses the “collapsible to avoid clutter” requirement.

Also applies to: 142-145

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@codeframe/tui/app.py` around lines 107 - 112, The Proof panel is always
mounted because there is no collapse state or toggle action; add a boolean state
(e.g., proof_panel_visible or proof_collapsed initialized appropriately) and a
new binding in BINDINGS like Binding("p", "toggle_proof", "Toggle Proof Panel")
and implement an action method action_toggle_proof that flips that state; update
the render/mount logic that currently always mounts the proof panel (references
to proof_panel, mount_proof_panel/unmount_proof_panel or the render method that
places the panel) to conditionally mount/render the proof panel only when
proof_panel_visible is true (or collapsed is false) so the panel can be toggled
to avoid clutter.
🧹 Nitpick comments (1)
tests/core/test_tui_dashboard.py (1)

190-217: Add a regression test for already-expired waivers.

Current proof tests validate “within 7 days” and “far future,” but not “already expired.” Adding that case will lock in the intended cutoff behavior.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/core/test_tui_dashboard.py` around lines 190 - 217, Add a new
regression test that creates a Requirement with status ReqStatus.WAIVED and a
Waiver whose expires date is in the past, saves it via
save_requirement(workspace, req), calls load_dashboard_data(workspace), and
asserts that the returned data.expiring_waivers includes this already-expired
waiver (or is handled as intended by load_dashboard_data); place the test
alongside test_load_non_expiring_waiver_excluded and use the same imports
(Requirement, Waiver, ReqStatus, save_requirement, load_dashboard_data) so the
behavior around expiration cutoff is enforced.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@codeframe/tui/data_service.py`:
- Around line 94-98: The expiring_waivers list currently includes
already-expired waivers because the condition (req.waiver.expires - today).days
<= 7 allows negative deltas; change the filter in the data.expiring_waivers
comprehension to only include waivers whose req.waiver.expires is not None and
whose expiration date is >= today and <= today + 7 days (or equivalently check 0
<= (req.waiver.expires - today).days <= 7) so expired items are excluded.

In `@tests/core/test_tui_dashboard.py`:
- Around line 133-135: Remove the unused GlitchType import from the import tuple
where Gate, GlitchType, Obligation, Requirement, RequirementScope, ReqStatus,
Severity, Source are imported; update the import statement (e.g., in the line
importing Gate, Obligation, Requirement, RequirementScope, ReqStatus, Severity,
Source) to exclude GlitchType so the unused-import (F401) CI error is resolved.

---

Outside diff comments:
In `@codeframe/tui/app.py`:
- Around line 107-112: The Proof panel is always mounted because there is no
collapse state or toggle action; add a boolean state (e.g., proof_panel_visible
or proof_collapsed initialized appropriately) and a new binding in BINDINGS like
Binding("p", "toggle_proof", "Toggle Proof Panel") and implement an action
method action_toggle_proof that flips that state; update the render/mount logic
that currently always mounts the proof panel (references to proof_panel,
mount_proof_panel/unmount_proof_panel or the render method that places the
panel) to conditionally mount/render the proof panel only when
proof_panel_visible is true (or collapsed is false) so the panel can be toggled
to avoid clutter.

---

Nitpick comments:
In `@tests/core/test_tui_dashboard.py`:
- Around line 190-217: Add a new regression test that creates a Requirement with
status ReqStatus.WAIVED and a Waiver whose expires date is in the past, saves it
via save_requirement(workspace, req), calls load_dashboard_data(workspace), and
asserts that the returned data.expiring_waivers includes this already-expired
waiver (or is handled as intended by load_dashboard_data); place the test
alongside test_load_non_expiring_waiver_excluded and use the same imports
(Requirement, Waiver, ReqStatus, save_requirement, load_dashboard_data) so the
behavior around expiration cutoff is enforced.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: b8555eee-1431-4d48-a810-e536c080b960

📥 Commits

Reviewing files that changed from the base of the PR and between e4cec8c and b0acbf3.

📒 Files selected for processing (3)
  • codeframe/tui/app.py
  • codeframe/tui/data_service.py
  • tests/core/test_tui_dashboard.py

Comment thread codeframe/tui/data_service.py
Comment thread tests/core/test_tui_dashboard.py
@claude

claude Bot commented Mar 20, 2026

Copy link
Copy Markdown

CodeFRAME Development Guidelines

Last updated: 2026-03-09

Product Vision

CodeFrame is a project delivery system: Think → Build → Prove → Ship.

It owns the edges of the AI coding pipeline — everything BEFORE code gets written (PRD, specification, task decomposition) and everything AFTER (verification gates, quality memory, deployment). The actual code writing is delegated to frontier coding agents (Claude Code, Codex, OpenCode) that are better at it than any custom agent.

CodeFrame does not compete with coding agents. It orchestrates them.

THINK:  cf prd generate → cf prd stress-test → cf tasks generate
BUILD:  cf work start --engine claude-code  (or codex, opencode, built-in)
PROVE:  cf proof run  (9-gate evidence-based quality system)
SHIP:   cf pr create → cf pr merge
LOOP:   Glitch → cf proof capture → New REQ → Enforced forever

Status: Phase 1 ✅ | Phase 2 ✅ | Phase 2.5 ✅ — CLI workflow, server layer, and ReAct agent complete. Agent adapter architecture (#408) and PROOF9 quality system (#422) are next priorities. See docs/V2_STRATEGIC_ROADMAP.md for the full plan.

If you are an agent working in this repo: do not improvise architecture. Follow the documents listed below.


Primary Contract (MUST FOLLOW)

  1. Golden Path: docs/GOLDEN_PATH.md
    The only workflow we build until it works end-to-end.

  2. Refactor Plan: docs/REFACTOR_PLAN_FOR_AGENT.md
    Step-by-step refactor instructions.

  3. Command Tree + Module Mapping: docs/CLI_WIREFRAME.md
    The authoritative map from CLI commands → core modules/functions.

  4. Agent Implementation: docs/AGENT_IMPLEMENTATION_TASKS.md
    Tracks the agent system components (all complete).

  5. Strategic Roadmap: docs/V2_STRATEGIC_ROADMAP.md
    5-phase plan from CLI to multi-agent.

Rule 0: If a change does not directly support the Think → Build → Prove → Ship pipeline, do not implement it.

Strategic Priority (Phase 4)

The next major architectural work is the Agent Adapter Architecture (#408):


Current Reality (Phase 1, 2 & 2.5 Complete)

What's Working Now

  • Full agent execution: cf work start <task-id> --execute (uses ReAct engine by default)
  • Engine selection: --engine react (default) or --engine plan (legacy)
  • Verbose mode: cf work start <task-id> --execute --verbose shows detailed progress
  • Dry run mode: cf work start <task-id> --execute --dry-run
  • Self-correction loop: Agent automatically fixes failing verification gates (up to 5 attempts with ReAct)
  • FAILED task status: Tasks can transition to FAILED for proper error visibility
  • Tech stack configuration: cf init . --detect auto-detects tech stack from project files
  • Project preferences: Agent loads AGENTS.md or CLAUDE.md for per-project configuration
  • Stall detection: Thread-based monitor with configurable recovery (--stall-action blocker|retry|fail)
  • Blocker detection: Agent creates blockers when stuck
  • Verification gates: Ruff/pytest checks after file changes
  • State persistence: Pause/resume across sessions
  • Batch execution: cf work batch run with serial/parallel/auto strategies
  • Task dependencies: depends_on field with dependency graph analysis
  • LLM dependency inference: --strategy auto analyzes task descriptions
  • Automatic retry: --retry N for failed task recovery
  • Batch resume: Re-run failed/blocked tasks from previous batches
  • Task scheduling: cf schedule show/predict/bottlenecks with CPM-based scheduling
  • Task templates: cf templates list/show/apply with 7 builtin templates
  • Effort estimation: Tasks support estimated_hours field for scheduling
  • Environment validation: cf env check/install/doctor validates tools and dependencies
  • GitHub PR workflow: cf pr create/status/checks/merge for PR management
  • Task self-diagnosis: cf work diagnose <task-id> analyzes failed tasks
  • 70+ integration tests: Comprehensive CLI test coverage
  • REST API: Full v2 API with 16 router modules (see Phase 2 below)
  • API authentication: API key auth with scopes (read/write/admin)
  • Rate limiting: Configurable per-endpoint rate limits
  • Real-time streaming: SSE for task execution events
  • OpenAPI documentation: Full Swagger/ReDoc at /docs and /redoc

v2 Architecture (current)

  • Core-first: Domain logic lives in codeframe/core/ (headless, no FastAPI imports)
  • CLI-first: Golden Path works without any running FastAPI server
  • Adapters: LLM providers in codeframe/adapters/llm/
  • Server/UI optional: FastAPI and UI are thin adapters over core

v1 Legacy

  • FastAPI server + WebSockets + React/Next.js dashboard retained for reference
  • Do not build toward v1 patterns during Golden Path work

Repository Structure

codeframe/
├── core/                    # Headless domain + orchestration (NO FastAPI imports)
│   ├── react_agent.py      # ReAct agent (default engine) - observe-think-act loop
│   ├── tools.py            # Tool definitions for ReAct agent (7 tools)
│   ├── editor.py           # Search-replace file editor with fuzzy matching
│   ├── agent.py            # Legacy plan-based agent (--engine plan)
│   ├── planner.py          # LLM-powered implementation planning (plan engine)
│   ├── executor.py         # Code execution engine with rollback (plan engine)
│   ├── context.py          # Task context loader with relevance scoring
│   ├── tasks.py            # Task management with depends_on field
│   ├── blockers.py         # Human-in-the-loop blocker system
│   ├── runtime.py          # Run lifecycle management
│   ├── conductor.py        # Batch orchestration with worker pool
│   ├── dependency_graph.py # DAG operations and execution planning
│   ├── dependency_analyzer.py # LLM-based dependency inference
│   ├── gates.py            # Verification gates (ruff, pytest, BUILD)
│   ├── fix_tracker.py      # Fix attempt tracking for loop prevention
│   ├── quick_fixes.py      # Pattern-based fixes without LLM
│   ├── agents_config.py    # AGENTS.md/CLAUDE.md preference loading
│   ├── workspace.py        # Workspace initialization
│   ├── prd.py              # PRD management
│   ├── events.py           # Event emission
│   ├── state_machine.py    # Task status transitions
│   ├── environment.py      # Environment validation and tool detection
│   ├── installer.py        # Automatic tool installation
│   ├── diagnostics.py      # Failed task analysis
│   ├── diagnostic_agent.py # AI-powered task diagnosis
│   ├── credentials.py      # API key and credential management
│   ├── stall_detector.py   # Synchronous stall detector + StallAction enum + StallDetectedError
│   ├── stall_monitor.py    # Thread-based stall watchdog with callback
│   ├── streaming.py        # Real-time output streaming for cf work follow
│   └── ...
├── adapters/
│   └── llm/                # LLM provider adapters
│       ├── base.py         # Protocol + ModelSelector + Purpose enum
│       ├── anthropic.py    # Anthropic Claude provider
│       └── mock.py         # Mock provider for testing
├── cli/
│   └── app.py              # Typer CLI entry + subcommands
├── ui/                     # FastAPI server (Phase 2 - thin adapter over core)
│   ├── server.py           # FastAPI app with OpenAPI configuration
│   ├── models.py           # Pydantic request/response models
│   ├── dependencies.py     # Shared dependencies (workspace, auth)
│   └── routers/            # API route handlers
│       ├── blockers_v2.py  # Blocker CRUD
│       ├── tasks_v2.py     # Task management + streaming
│       ├── prd_v2.py       # PRD management + versioning
│       ├── workspace_v2.py # Workspace init and status
│       ├── batches_v2.py   # Batch execution
│       ├── streaming_v2.py # SSE event streaming
│       ├── api_key_v2.py   # API key management
│       └── ...             # 16 router modules total
├── lib/                    # Shared utilities
│   ├── rate_limiter.py     # SlowAPI rate limiting
│   └── audit_logger.py     # Request audit logging
├── auth/                   # Authentication
│   ├── api_key_service.py  # API key creation/validation
│   └── dependencies.py     # Auth dependencies
├── config/
│   └── rate_limits.py      # Rate limit configuration
└── server/                 # Legacy server code (reference only)

web-ui/                     # Frontend (legacy, reference only)
tests/
├── core/                   # Core module tests
│   ├── test_agent.py
│   ├── test_executor.py
│   ├── test_planner.py
│   ├── test_context.py
│   ├── test_conductor.py
│   ├── test_dependency_graph.py
│   ├── test_dependency_analyzer.py
│   ├── test_task_dependencies.py
│   └── ...
└── adapters/
    └── test_llm.py

Architecture Rules (non-negotiable)

1) Core must be headless

codeframe/core/** must NOT import:

  • FastAPI
  • WebSocket frameworks
  • HTTP request/response objects
  • UI modules

Core is allowed to:

  • read/write durable state (SQLite/filesystem)
  • run orchestration/worker loops
  • emit events to an append-only event log
  • call adapters via interfaces (LLM, git, fs)

2) CLI must not require a server

Golden Path commands must work from the CLI with no server running.

FastAPI is optional and must be started explicitly (e.g., codeframe serve) and must wrap core.

3) Agent state transitions flow through runtime

Critical pattern discovered during implementation:

  • Agent (agent.py) manages its own AgentState (IDLE, PLANNING, EXECUTING, BLOCKED, COMPLETED, FAILED)
  • Runtime (runtime.py) handles all TaskStatus transitions (BACKLOG, READY, IN_PROGRESS, DONE, BLOCKED)
  • Agent does NOT call tasks.update_status() - runtime does this based on agent state

This separation prevents duplicate state transitions (e.g., DONE→DONE, BLOCKED→BLOCKED errors).

4) Legacy can be read, not depended on

Legacy code is reference material.

  • Copy/simplify logic into core when useful
  • Do NOT import legacy UI/server modules into core
  • Do NOT "fix the UI" during Golden Path work

5) Keep commits runnable

At all times:

  • codeframe --help works
  • Golden Path command stubs can run
  • Avoid breaking the repo with large renames/moves

Agent System Architecture

Components

Component File Purpose
ReactAgent core/react_agent.py Default engine: observe-think-act loop with tool use
Tools core/tools.py 7 agent tools: read/edit/create file, run command/tests, search, list
Editor core/editor.py Search-replace editor with 4-level fuzzy matching
Stall Detector core/stall_detector.py Synchronous stall check + StallAction enum + StallDetectedError
Stall Monitor core/stall_monitor.py Thread-based watchdog with callback (integrated into ReactAgent)
LLM Adapter adapters/llm/base.py Protocol, ModelSelector, Purpose enum
Anthropic Provider adapters/llm/anthropic.py Claude integration with streaming
Mock Provider adapters/llm/mock.py Testing with call tracking
Context Loader core/context.py Codebase scanning, relevance scoring
Planner core/planner.py Task → ImplementationPlan via LLM (plan engine)
Executor core/executor.py File ops, shell commands, rollback (plan engine)
Agent (legacy) core/agent.py Plan-based orchestration (--engine plan)
Runtime core/runtime.py Run lifecycle, engine selection, agent invocation
Conductor core/conductor.py Batch orchestration, worker pool
Dependency Graph core/dependency_graph.py DAG operations, topological sort
Dependency Analyzer core/dependency_analyzer.py LLM-based dependency inference
Environment Validator core/environment.py Tool detection and validation
Installer core/installer.py Automatic tool installation
Diagnostics core/diagnostics.py Failed task analysis
Diagnostic Agent core/diagnostic_agent.py AI-powered task diagnosis
Credentials core/credentials.py API key and credential management
Event Publisher core/streaming.py Real-time SSE event distribution
API Key Service auth/api_key_service.py API key CRUD and validation
Rate Limiter lib/rate_limiter.py Per-endpoint rate limiting

Model Selection Strategy

Task-based heuristic via Purpose enum:

  • PLANNING → claude-sonnet-4-20250514 (complex reasoning)
  • EXECUTION → claude-sonnet-4-20250514 (balanced)
  • GENERATION → claude-haiku-4-20250514 (fast/cheap)

Future: cf tasks set provider <id> <provider> for per-task override.

Engine Selection

CodeFRAME supports two execution engines, selected via --engine:

Engine Flag Pattern Best For
ReAct (default) --engine react Observe → Think → Act loop Most tasks, adaptive execution
Plan (legacy) --engine plan Plan all steps → Execute sequentially Well-defined, predictable tasks

Execution Flow (ReAct — default)

cf work start <id> --execute [--verbose]
    │
    ├── runtime.start_task_run()      # Creates run, transitions task→IN_PROGRESS
    │
    └── runtime.execute_agent(engine="react")
            │
            └── ReactAgent.run(task_id)
                ├── Load context (PRD, codebase, blockers, AGENTS.md, tech_stack)
                ├── Build layered system prompt
                │
                └── Tool-use loop (until complete/blocked/failed):
                    ├── Check stall detector (configurable: retry/blocker/fail)
                    ├── LLM decides next action (tool call)
                    ├── Execute tool: read_file, edit_file, create_file,
                    │   run_command, run_tests, search_codebase, list_files
                    ├── Observe result → feed back to LLM
                    ├── Record activity (resets stall timer)
                    ├── Incremental verification (ruff after file changes)
                    └── Token budget management (3-tier compaction)
                │
                └── Final verification with self-correction (up to 5 retries)
                │
                └── Update run/task status based on agent result
                    ├── COMPLETED → complete_run() → task→DONE
                    ├── BLOCKED → block_run() → task→BLOCKED
                    └── FAILED → fail_run() → task→FAILED

Execution Flow (Plan — legacy, --engine plan)

cf work start <id> --execute --engine plan
    │
    ├── runtime.start_task_run()
    │
    └── runtime.execute_agent(engine="plan")
            │
            ├── agent.run(task_id)
            │   ├── Load context (PRD, codebase, blockers, AGENTS.md)
            │   ├── Create plan via LLM
            │   ├── Execute steps (file create/edit, shell commands)
            │   ├── Run incremental verification (ruff)
            │   ├── Detect blockers (consecutive failures, missing files)
            │   └── Run final verification with SELF-CORRECTION LOOP:
            │       ├── Run all gates (pytest, ruff)
            │       ├── If failed: _attempt_verification_fix()
            │       │   ├── Try ruff --fix for quick lint fixes
            │       │   ├── Use LLM to generate fix plan from errors
            │       │   └── Execute fix steps
            │       └── Retry up to max_attempts (default: 3)
            │
            └── Update run/task status based on agent result
                ├── COMPLETED → complete_run() → task→DONE
                ├── BLOCKED → block_run() → task→BLOCKED
                └── FAILED → fail_run() → task→FAILED

Commands (v2 CLI)

Python (preferred)

Use uv for Python tasks:

uv run pytest
uv run pytest tests/core/  # Core module tests only
uv run ruff check .

CLI (Golden Path)

# Workspace
cf init <repo>                                    # Initialize workspace
cf init <repo> --detect                           # Initialize + auto-detect tech stack
cf init <repo> --tech-stack "Python with uv"      # Initialize + explicit tech stack
cf init <repo> --tech-stack-interactive           # Initialize + interactive setup
cf status

# PRD
cf prd add <file.md>
cf prd show

# Tasks
cf tasks generate          # Uses LLM to generate from PRD
cf tasks list
cf tasks list --status READY
cf tasks show <id>

# Work execution (single task)
cf work start <task-id>                    # Creates run record
cf work start <task-id> --execute          # Runs AI agent (ReAct engine, default)
cf work start <task-id> --execute --engine plan  # Use legacy plan engine
cf work start <task-id> --execute --verbose  # With detailed output
cf work start <task-id> --execute --dry-run  # Preview changes
cf work start <task-id> --execute --stall-timeout 120  # Custom stall timeout (0=disabled)
cf work start <task-id> --execute --stall-action retry  # Recovery: blocker|retry|fail
cf work stop <task-id>                     # Cancel stale run
cf work resume <task-id>                   # Resume blocked work
cf work follow <task-id>                   # Stream real-time output
cf work follow <task-id> --tail 50         # Show last 50 lines then stream

# Batch execution (multiple tasks)
cf work batch run <id1> <id2> ...          # Execute multiple tasks (ReAct default)
cf work batch run --all-ready              # All READY tasks
cf work batch run --all-ready --engine plan  # Use legacy plan engine
cf work batch run --strategy serial        # Serial (default)
cf work batch run --strategy parallel      # Parallel execution
cf work batch run --strategy auto          # LLM-inferred dependencies
cf work batch run --max-parallel 4         # Concurrent limit
cf work batch run --retry 3               # Auto-retry failures
cf work batch status [batch_id]            # Show batch status
cf work batch cancel <batch_id>            # Cancel running batch
cf work batch resume <batch_id>            # Re-run failed tasks

# Blockers
cf blocker list
cf blocker show <id>
cf blocker answer <id> "answer"

# Quality
cf review
cf patch export
cf commit

# State
cf checkpoint create "name"
cf checkpoint list
cf checkpoint restore <id>
cf summary

# Environment validation
cf env check                     # Validate tools and dependencies
cf env install                   # Install missing tools
cf env doctor                    # Comprehensive environment health check

# GitHub PR workflow
cf pr create                     # Create PR from current branch
cf pr status                     # Show PR status
cf pr checks                     # Show CI check results
cf pr merge                      # Merge approved PR

# Diagnostics
cf work diagnose <task-id>       # AI-powered analysis of failed tasks

Note: codeframe serve exists but Golden Path does not depend on it.

Frontend (legacy)

cd web-ui && npm test
cd web-ui && npm run build

Do not expand frontend scope during Golden Path work.


Documentation Navigation

Authoritative (v2)

  • docs/GOLDEN_PATH.md - CLI-first workflow contract
  • docs/REFACTOR_PLAN_FOR_AGENT.md - Step-by-step refactor instructions
  • docs/CLI_WIREFRAME.md - Command → module mapping
  • docs/AGENT_IMPLEMENTATION_TASKS.md - Agent system components
  • docs/V2_STRATEGIC_ROADMAP.md - 5-phase plan from CLI to multi-agent

Agent Architecture (Phase 2.5)

  • docs/AGENT_V3_UNIFIED_PLAN.md - ReAct architecture design and rules
  • docs/REACT_AGENT_ARCHITECTURE.md - Deep-dive: tools, editor, token management
  • docs/REACT_AGENT_ANALYSIS.md - Golden path test run analysis

API Documentation (Phase 2)

  • /docs - Swagger UI (interactive API explorer)
  • /redoc - ReDoc (readable API documentation)
  • /openapi.json - OpenAPI 3.1 specification
  • docs/PHASE_2_DEVELOPER_GUIDE.md - Server layer implementation guide
  • docs/PHASE_2_CLI_API_MAPPING.md - CLI to API endpoint mapping

Legacy (v1 reference only)

These describe old server/UI-driven architecture:

  • SPRINTS.md, sprints/
  • specs/
  • CODEFRAME_SPEC.md
  • v1 feature docs (context/session/auth/UI state management)

What NOT to do (common agent failure modes)

  • Don't add new HTTP endpoints to support the CLI
  • Don't require codeframe serve for CLI workflows
  • Don't implement UI concepts (tabs, panels, progress bars) inside core
  • Don't redesign auth, websockets, or UI state management
  • Don't add multi-providers/model switching features before Golden Path works
  • Don't "clean up the repo" as a goal - only refactor to enable Golden Path
  • Don't update task status from agent.py - let runtime handle transitions

Testing / Demoing CodeFRAME on Sample Projects

When running uv run cf commands against a sample project (e.g., cf-test/) to test or demo CodeFRAME's capabilities, you are observing the CodeFRAME agent's work, not doing the work yourself.

Rules for testing/demo mode:

  • You are evaluating how well the CodeFRAME agent (ReAct or Plan engine) builds the project
  • Do NOT help out, fix errors, or write code on behalf of the CodeFRAME agent
  • Do NOT intervene when the agent makes mistakes — that's data
  • Your job is to report the process: what worked, what failed, how close the agent got
  • Document the agent's output, errors encountered, and final state
  • Assess completion against the PRD/acceptance criteria objectively
  • If the agent gets stuck or fails, report that as a finding — don't rescue it

This applies when using commands like cf work start <id> --execute, cf work batch run, or any command that triggers the AI agent to do implementation work on a target project.


Practical Working Mode for Agents

When implementing anything, do this loop:

  1. Read docs/GOLDEN_PATH.md and confirm the change is required
  2. Find the command in docs/CLI_WIREFRAME.md
  3. Implement core functionality in codeframe/core/
  4. Call it from Typer command in codeframe/cli/
  5. Emit events + persist state
  6. Keep it runnable. Commit.

If you are unsure which direction to take, default to:

  • simpler state
  • fewer dependencies
  • smaller surface area
  • core-first, CLI-first

Recent Updates (2026-03-09)

Stall Detection System (#399, #400, #401)

Complete stall detection and configurable recovery for agent execution:

Components:

  • StallMonitor (core/stall_monitor.py) — Thread-based watchdog polling every 5s
  • StallDetector (core/stall_detector.py) — Synchronous time-tracking primitive
  • StallAction enum — Recovery strategy: RETRY, BLOCKER, FAIL
  • StallDetectedError — Exception for RETRY path (propagates to runtime for retry)

CLI flags:

  • --stall-timeout N — Seconds without tool activity before stall (default: 300, 0=disabled)
  • --stall-action {blocker,retry,fail} — Recovery action (default: blocker)
  • Both flags available on cf work start and cf work batch run

Recovery flow:

  • BLOCKER (default): Creates informative blocker, task → BLOCKED
  • RETRY: Raises StallDetectedError, runtime retries once with fresh agent
  • FAIL: Task transitions directly to FAILED

Config: agent_budget.stall_timeout_s in .codeframe/config.yaml (0 = disabled)


Phase 2.5 Complete: ReAct Agent Architecture (#355)

Default execution engine switched from plan-based to ReAct (Reasoning + Acting).

What changed:

  • Default engine is now "react" — all cf work start --execute and cf work batch run commands use ReactAgent
  • Legacy plan engine available via --engine plan flag
  • ReactAgent uses iterative tool-use loop (observe → think → act) instead of plan-all-then-execute
  • 7 structured tools: read_file, edit_file, create_file, run_command, run_tests, search_codebase, list_files
  • Search-replace editing with 4-level fuzzy matching (exact → whitespace-normalized → indentation-agnostic → fuzzy)
  • Token budget management with 3-tier compaction
  • Adaptive iteration budget based on task complexity

Phase 2.5 deliverables:

Phase Focus Pipeline Stage Status
1 CLI Completion Think + Build Complete
2 Server Layer Build (API) Complete
2.5 ReAct Agent Build (execution) Complete
3 Web UI Rebuild All (dashboard) In Progress
4 Agent Adapters + Orchestration Build (delegate to frontier agents) Next
5 PROOF9 + Advanced Prove + Ship (quality memory) Planned

Phase 2 Complete: Server Layer (2026-02-03)

Phase 2 deliverables completed:

Server Architecture (Phase 2)

Pattern: Thin adapter over core - server routes delegate to core.* modules.

CLI (typer) ─┬── core.* ─── adapters.*
             │
Server (fastapi) ─┘

V2 Router Modules (16 total):

Router Endpoints Purpose
blockers_v2 5 Blocker CRUD
prd_v2 8 PRD management + versioning
tasks_v2 12 Task management + streaming
workspace_v2 5 Init, status, tech stack
batches_v2 5 Batch execution strategies
streaming_v2 2 SSE event streaming
api_key_v2 4 API key management
discovery_v2 5 PRD discovery sessions
checkpoints_v2 6 State checkpoints
schedule_v2 3 Task scheduling
templates_v2 4 PRD templates
git_v2 3 Git operations
review_v2 2 Code review
pr_v2 5 GitHub PR workflow
environment_v2 4 Tool detection
proof_v2 7 PROOF9 quality gates + requirements

API Authentication:

# Create API key
cf auth api-key-create --name "my-key" --scopes read,write

# Use in requests
curl -H "X-API-Key: cf_..." https://api.example.com/api/v2/tasks

Rate Limiting:

  • Default: 100 requests/minute (standard endpoints)
  • Auth endpoints: 10/minute
  • AI endpoints: 20/minute
  • Configurable via RATE_LIMIT_* environment variables

OpenAPI Documentation:

  • Swagger UI: /docs
  • ReDoc: /redoc
  • OpenAPI JSON: /openapi.json

Previous Updates (2026-01-29)

V2 Strategic Roadmap Established

Created comprehensive 5-phase roadmap in docs/V2_STRATEGIC_ROADMAP.md.

Phase 1 Complete: CLI Foundation

All Phase 1 priorities completed:

Environment Validation (cf env)

New commands for validating development environment:

cf env check              # Validate required tools (git, uv, ruff, pytest)
cf env install            # Install missing tools automatically
cf env doctor             # Comprehensive environment health check

Modules:

  • core/environment.py - Tool detection and validation
  • core/installer.py - Cross-platform tool installation

GitHub PR Workflow (cf pr)

Streamlined PR management without leaving the CLI:

cf pr create              # Create PR from current branch
cf pr status              # Show PR status and review state
cf pr checks              # Show CI check results
cf pr merge               # Merge approved PR

Task Self-Diagnosis (cf work diagnose)

AI-powered analysis of failed tasks:

cf work diagnose <task-id>   # Analyze why a task failed

Modules:

  • core/diagnostics.py - Failed task analysis
  • core/diagnostic_agent.py - AI-powered diagnosis

Bug Fixes

GitHub Issue Organization


Previous Updates (2026-01-16)

Phase 3.1: Tech Stack Configuration

Simplified tech stack configuration using natural language descriptions:

  1. tech_stack field on Workspace model - stores natural language description
  2. --detect flag - auto-detects from pyproject.toml, package.json, Cargo.toml, go.mod
  3. --tech-stack flag - explicit tech stack description (e.g., "Rust project with cargo")
  4. --tech-stack-interactive flag - simple prompt for user input (stub for future multi-round)
  5. Agent integration - TaskContext and Planner include tech_stack in LLM prompts
  6. Removed cf config subcommand - tech stack is now part of workspace init

Design philosophy: Instead of structured configuration with specific package managers and frameworks, users describe their stack in natural language. The agent interprets and adapts.

Examples:

cf init . --detect                           # Auto-detect: "Python with uv, pytest, ruff for linting"
cf init . --tech-stack "Rust project using cargo"
cf init . --tech-stack "TypeScript monorepo with pnpm, Next.js, jest"
cf init . --tech-stack-interactive           # Prompts user for description

Future work: Multi-round interactive discovery (bead: codeframe-8d80)


Agent Self-Correction & Observability

Improved agent reliability with automatic error recovery:

  1. Self-correction loop in _run_final_verification() - agent retries up to 3 times
  2. Verbose mode (--verbose / -v) - shows detailed verification/self-correction progress
  3. FAILED task status - tasks transition to FAILED for proper error visibility
  4. Project preferences - agent loads AGENTS.md/CLAUDE.md for per-project config
  5. Fixed fail_run() - now properly transitions task status (was leaving tasks stuck)

Enhanced Self-Correction (Phase 3.4)

Advanced error recovery with loop prevention and smart escalation:

  1. Fix Attempt Tracker (core/fix_tracker.py) - prevents repeating failed fixes

    • Normalizes errors for comparison (removes line numbers, memory addresses)
    • Tracks (error_signature, fix_description) pairs with outcomes
    • Detects escalation patterns (same error 3+ times, same file 3+ times)
  2. Pattern-Based Quick Fixes (core/quick_fixes.py) - fixes common errors without LLM

    • ModuleNotFoundError → auto-install package (detects package manager)
    • ImportError → add missing import statement
    • NameError → add common imports (Optional, dataclass, Path, etc.)
    • SyntaxError → fix missing colons, f-string prefixes
    • IndentationError → normalize mixed tabs/spaces
  3. Escalation to Blocker - creates informative blockers when stuck

    • Triggered after MAX_SAME_ERROR_ATTEMPTS (3) failures on same error
    • Triggered after MAX_SAME_FILE_ATTEMPTS (3) failures on same file
    • Triggered after MAX_TOTAL_FAILURES (5) in a run
    • Blocker includes error type, attempted fixes, and guidance questions

Self-Correction Flow

Error occurs
    │
    ├── Try ruff --fix (auto-lint)
    │
    ├── Try pattern-based quick fix (no LLM)
    │   ├── Check if fix already attempted → skip
    │   ├── Apply fix
    │   └── Record outcome in tracker
    │
    ├── Check escalation threshold
    │   └── If exceeded → create escalation blocker
    │
    └── Use LLM to generate fix plan
        ├── Include already-tried fixes to avoid repetition
        ├── Execute fix steps with tracking
        └── Re-verify

Key Self-Correction Methods

  • _run_final_verification(): While loop that re-runs gates after self-correction
  • _attempt_verification_fix(): Orchestrates quick fixes, escalation check, LLM fixes
  • _create_escalation_blocker(): Creates detailed blocker with context
  • _verbose_print(): Conditional stdout output for observability

Phase 2 Complete (2026-01-15): Parallel Batch Execution

All 6 Phase 2 items from CLI_WIREFRAME.md are done:

  1. work batch resume <batch-id> - re-run failed/blocked tasks
  2. depends_on field on Task model
  3. ✅ Dependency graph analysis (DAG, cycle detection, topological sort)
  4. ✅ True parallel execution with ThreadPoolExecutor worker pool
  5. --strategy auto with LLM-based dependency inference
  6. --retry N automatic retry of failed tasks

Key Phase 2 Modules

  • conductor.py: Batch orchestration with serial/parallel/auto strategies
  • dependency_graph.py: DAG operations, level-based grouping for parallelization
  • dependency_analyzer.py: LLM analyzes task descriptions to infer dependencies

Agent Implementation Complete (2026-01-14)

All 8 implementation tasks from AGENT_IMPLEMENTATION_TASKS.md are done:

  1. ✅ LLM Adapter Interface (adapters/llm/)
  2. ✅ Task Context Loader (core/context.py)
  3. ✅ Agent Planning (core/planner.py)
  4. ✅ Code Execution Engine (core/executor.py)
  5. ✅ Automatic Blocker Detection (in core/agent.py)
  6. ✅ Gate Integration (in core/agent.py)
  7. ✅ Agent Orchestrator (core/agent.py)
  8. ✅ Wire into Runtime (core/runtime.py)

Bug Fixes During Testing

  • GateResult attribute access: Fixed gate_result.statusgate_result.passed
  • Duplicate task transitions: Removed task status updates from agent.py (runtime handles all)
  • READY→READY error: Added check in stop_run before transitioning
  • Verification step handling: Made _execute_verification smarter about file vs command targets

Key Design Decisions

  • State separation: Agent manages AgentState, Runtime manages TaskStatus
  • Model selection: Task-based heuristic via Purpose enum
  • Blocker creation: Agent creates blockers, Runtime updates task status
  • Verification: Incremental (ruff after each file change) + final (all gates)

Testing

Run all tests

uv run pytest

Run v2 tests only

uv run pytest -m v2           # All v2 tests (~411 tests)
uv run pytest -m v2 -q        # Quiet mode

The v2 marker identifies tests for CLI-first, headless functionality:

  • All tests in tests/core/ are automatically marked v2 (via conftest.py)
  • v2 CLI tests have pytestmark = pytest.mark.v2 at the top

Convention: When adding new v2 functionality, mark tests with @pytest.mark.v2 or add pytestmark = pytest.mark.v2 at module level for CLI tests that use codeframe.cli.app.

Run core module tests

uv run pytest tests/core/
uv run pytest tests/core/test_agent.py -v
uv run pytest tests/adapters/test_llm.py -v

Test coverage

uv run pytest --cov=codeframe --cov-report=html

Environment Variables

# Required for agent execution
ANTHROPIC_API_KEY=sk-ant-...

# Optional - Database
DATABASE_PATH=./codeframe.db

# Optional - Rate Limiting (Phase 2)
RATE_LIMIT_ENABLED=true                    # Enable/disable rate limiting
RATE_LIMIT_DEFAULT=100/minute              # Default limit
RATE_LIMIT_AUTH=10/minute                  # Auth endpoints
RATE_LIMIT_AI=20/minute                    # AI/LLM endpoints
RATE_LIMIT_WEBSOCKET=50/minute             # WebSocket connections
REDIS_URL=redis://localhost:6379           # Redis for distributed rate limiting (optional)

# Optional - API Server
CODEFRAME_API_KEY_SECRET=<random-secret>   # Secret for API key hashing

Legacy sections removed on purpose

This file previously contained extensive v1 details (auth, websocket, UI template, sprint history).
Those are still in git history and legacy docs, but they are not the current contract.

The current contract is Golden Path + Refactor Plan + Command Tree mapping + Agent Implementation.

@claude

claude Bot commented Mar 20, 2026

Copy link
Copy Markdown

Follow-up review: The PR has not been updated since the initial round of reviews. Four items remain before merge. (1) Move 'from datetime import date' to top-level imports in app.py - it is currently inside the for-loop body at ~line 233. (2) Semantic mismatch: open_obligation_count is set to len(open_reqs) which counts requirements, not obligation-gate pairs - either rename to open_requirement_count and update the badge label, or sum len(r.obligations) across reqs to match the name. (3) Expired waiver handling needs two fixes: the filter '(req.waiver.expires - today).days <= 7' allows negative deltas so change it to '0 <= days <= 7', and the render shows 'expires in Nd' for negatives so clamp expired waivers to show EXPIRED instead. (4) Remove the unused GlitchType import in tests (~line 133) to clear the F401 lint warning. Items that can be follow-up issues: missing test for waiver.expires=None, missing test for already-expired waiver rendering, right-column density and collapsible panel UX.

@frankbria

Copy link
Copy Markdown
Owner Author

CodeRabbit Review Response

Fixed (2 items):

  • ✅ Unused GlitchType import removed (ruff F401 — already pushed before review)
  • ✅ Expired waivers excluded from expiring_waivers — added lower bound 0 <= so past-expiry waivers are not shown as "expiring soon". Added test_already_expired_waiver_excluded to cover this case.

@claude

claude Bot commented Mar 20, 2026

Copy link
Copy Markdown

Follow-up review: Two items remain open from my previous reviews.

Still needs fixing before merge:

1. from datetime import date inside the for loop (app.py ~line 233)
The import is still inside the loop body:

for req in data.expiring_waivers:
    from datetime import date   # ← still here
    days = (req.waiver.expires - date.today()).days

Move it to the top-level imports in app.py. Python caches the import so there's no runtime cost, but it's a PEP 8 violation and ruff will eventually flag it.

2. Semantic mismatch: open_obligation_count vs len(open_reqs) (data_service.py ~line 85)
This was raised in both my first review and follow-up but hasn't been addressed. The field is named open_obligation_count but counts requirements (one requirement can have multiple gate obligations). The status bar badge reads "X open obligations" but it counts requirements. Pick one and be consistent:

  • Rename to open_requirement_count and change the badge label to "X open requirements", or
  • Compute sum(len(r.obligations) for r in open_reqs) to actually count obligations.

Edge case (minor, can be follow-up):

The filter now correctly excludes expired waivers (0 <= bound — good). But a waiver expiring today passes the filter and renders as "expires in 0d", which is misleading. A small fix would be:

days = (req.waiver.expires - date.today()).days
label = f"expires in {days}d" if days > 0 else "expires today"

This is not blocking but would improve UX.

Items 3 (expired-waiver filter) and 4 (GlitchType import) are confirmed fixed — appreciate the quick turnaround on those.

@frankbria
frankbria merged commit 695340f into main Mar 20, 2026
10 checks passed
@frankbria
frankbria deleted the feat/tui-proof-panel-457 branch March 24, 2026 23:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

PROOF9: TUI dashboard has no proof panel

1 participant