feat(tui): PROOF9 obligations panel in TUI dashboard - #460
Conversation
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
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
🚧 Files skipped from review as they are similar to previous changes (2)
WalkthroughAdds 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 ( Changes
Sequence DiagramsequenceDiagram
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
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
Code Review:
|
There was a problem hiding this comment.
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 | 🟠 MajorProof 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
📒 Files selected for processing (3)
codeframe/tui/app.pycodeframe/tui/data_service.pytests/core/test_tui_dashboard.py
CodeFRAME Development GuidelinesLast updated: 2026-03-09 Product VisionCodeFrame 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. 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 If you are an agent working in this repo: do not improvise architecture. Follow the documents listed below. Primary Contract (MUST FOLLOW)
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
v2 Architecture (current)
v1 Legacy
Repository StructureArchitecture Rules (non-negotiable)1) Core must be headless
Core is allowed to:
2) CLI must not require a serverGolden Path commands must work from the CLI with no server running. FastAPI is optional and must be started explicitly (e.g., 3) Agent state transitions flow through runtimeCritical pattern discovered during implementation:
This separation prevents duplicate state transitions (e.g., DONE→DONE, BLOCKED→BLOCKED errors). 4) Legacy can be read, not depended onLegacy code is reference material.
5) Keep commits runnableAt all times:
Agent System ArchitectureComponents
Model Selection StrategyTask-based heuristic via
Future: Engine SelectionCodeFRAME supports two execution engines, selected via
Execution Flow (ReAct — default)Execution Flow (Plan — legacy,
|
| 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 audit and refactor ([Phase 2] Server audit and refactor - routes delegating to core modules #322) - 16 v2 routers following thin adapter pattern
- ✅ API key authentication (feat(auth): add API key authentication for CLI and REST API #326) - Scopes: read/write/admin
- ✅ Rate limiting (feat(security): add API rate limiting with slowapi #327) - Configurable per-endpoint with Redis support
- ✅ Real-time SSE streaming (feat(streaming): add real-time SSE events for task execution #328) -
/api/v2/tasks/{id}/stream - ✅ OpenAPI documentation ([Phase 2] Complete OpenAPI documentation for all endpoints #119) - Full Swagger/ReDoc with examples
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/tasksRate 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:
- ✅
cf prd generate- Socratic PRD discovery ([Phase 1] cf prd generate - Interactive AI PRD creation (Socratic Discovery) #307) - ✅
cf work follow- Live execution streaming ([Phase 1] cf work follow - Live execution streaming #308) - ✅ Integration tests for credential/env modules ([Phase 1] Integration tests for credential and environment modules #309)
- ✅ PRD template system ([Phase 1] PRD template system for customizable output formats #316)
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 checkModules:
core/environment.py- Tool detection and validationcore/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 PRTask Self-Diagnosis (cf work diagnose)
AI-powered analysis of failed tasks:
cf work diagnose <task-id> # Analyze why a task failedModules:
core/diagnostics.py- Failed task analysiscore/diagnostic_agent.py- AI-powered diagnosis
Bug Fixes
- [Phase 1] Backend: NoneType error accessing search_pattern during task execution #265: Fixed NoneType error in
codebase_index.search_pattern()- added null check - [Phase 1] Checkpoint diff API returns 500 - workspace directory missing #253: Fixed checkpoint diff API returning 500 - added workspace existence validation
GitHub Issue Organization
- Created
v1-legacylabel for 22 v1-specific issues (closed, retained as Phase 3 reference) - Created phase labels:
phase-1,phase-2,phase-4,phase-5 - Created 9 new issues ([Phase 1] cf prd generate - Interactive AI PRD creation (Socratic Discovery) #307-[Phase 5] Debug and replay mode #315) for roadmap features
- Consistent naming:
[Phase #] Titleformat
Previous Updates (2026-01-16)
Phase 3.1: Tech Stack Configuration
Simplified tech stack configuration using natural language descriptions:
- ✅
tech_stackfield on Workspace model - stores natural language description - ✅
--detectflag - auto-detects from pyproject.toml, package.json, Cargo.toml, go.mod - ✅
--tech-stackflag - explicit tech stack description (e.g., "Rust project with cargo") - ✅
--tech-stack-interactiveflag - simple prompt for user input (stub for future multi-round) - ✅ Agent integration - TaskContext and Planner include tech_stack in LLM prompts
- ✅ Removed
cf configsubcommand - 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 descriptionFuture work: Multi-round interactive discovery (bead: codeframe-8d80)
Agent Self-Correction & Observability
Improved agent reliability with automatic error recovery:
- ✅ Self-correction loop in
_run_final_verification()- agent retries up to 3 times - ✅ Verbose mode (
--verbose/-v) - shows detailed verification/self-correction progress - ✅ FAILED task status - tasks transition to FAILED for proper error visibility
- ✅ Project preferences - agent loads AGENTS.md/CLAUDE.md for per-project config
- ✅ 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:
-
✅ 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)
-
✅ Pattern-Based Quick Fixes (
core/quick_fixes.py) - fixes common errors without LLMModuleNotFoundError→ auto-install package (detects package manager)ImportError→ add missing import statementNameError→ add common imports (Optional, dataclass, Path, etc.)SyntaxError→ fix missing colons, f-string prefixesIndentationError→ normalize mixed tabs/spaces
-
✅ 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:
- ✅
work batch resume <batch-id>- re-run failed/blocked tasks - ✅
depends_onfield on Task model - ✅ Dependency graph analysis (DAG, cycle detection, topological sort)
- ✅ True parallel execution with ThreadPoolExecutor worker pool
- ✅
--strategy autowith LLM-based dependency inference - ✅
--retry Nautomatic 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:
- ✅ LLM Adapter Interface (
adapters/llm/) - ✅ Task Context Loader (
core/context.py) - ✅ Agent Planning (
core/planner.py) - ✅ Code Execution Engine (
core/executor.py) - ✅ Automatic Blocker Detection (in
core/agent.py) - ✅ Gate Integration (in
core/agent.py) - ✅ Agent Orchestrator (
core/agent.py) - ✅ Wire into Runtime (
core/runtime.py)
Bug Fixes During Testing
- GateResult attribute access: Fixed
gate_result.status→gate_result.passed - Duplicate task transitions: Removed task status updates from agent.py (runtime handles all)
- READY→READY error: Added check in
stop_runbefore transitioning - Verification step handling: Made
_execute_verificationsmarter 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 pytestRun v2 tests only
uv run pytest -m v2 # All v2 tests (~411 tests)
uv run pytest -m v2 -q # Quiet modeThe 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.v2at 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 -vTest coverage
uv run pytest --cov=codeframe --cov-report=htmlEnvironment 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 hashingLegacy 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.
|
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. |
CodeRabbit Review ResponseFixed (2 items):
|
|
Follow-up review: Two items remain open from my previous reviews. Still needs fixing before merge: 1. for req in data.expiring_waivers:
from datetime import date # ← still here
days = (req.waiver.expires - date.today()).daysMove it to the top-level imports in 2. Semantic mismatch:
Edge case (minor, can be follow-up): The filter now correctly excludes expired waivers ( 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. |
Summary
Closes #457.
Adds a ProofPanel to the CodeFRAME TUI dashboard, giving users visibility into PROOF9 obligations without leaving the terminal.
Changes
data_service.pyDashboardDatagains 3 new fields:open_requirements,expiring_waivers,open_obligation_countload_dashboard_datafetches proof data in a new read-only try/except block (no DB mutations — explicitly avoidscheck_expired_waivers)app.py#proof-panelwidget (amber$warningborder) added below#blocker-panelin the right column_update_proof_panel()renders:⚠ REQ-001: waiver expires in 3d — ...REQ-002 high Auth token not validated | UNIT ⏳ SEC ✅StatusBarshowsN open obligationsbadge when count > 0Test plan
tests/core/test_tui_dashboard.py— all passingruff checkcleanSummary by CodeRabbit