Archive completed tasks, add cleanup commands, self-documenting dashboard UI
CI / build (push) Has been cancelled

- Archive 79 completed framework-dev tasks from tasks/ -> tasks/complete/
- status.py: add --cleanup-done and --install-cleanup-schedule commands
- Add scripts/automaton-cleanup.sh for periodic task archiving
- Dashboard: rename 'Background' tab -> 'Agent', 'Cleanup' agent -> 'Completed Task Archiver', remove redundant group headers and pill badges, dim inactive agent placeholders
- .rules.md: add Self-Documenting UI Names rule
- New tests: test_cleanup_done.py, expanded test_app.py and test_task.py
This commit is contained in:
Lap Tran
2026-06-24 22:43:33 -04:00
parent e13513faaa
commit 4a2301b077
572 changed files with 856 additions and 101 deletions
@@ -0,0 +1,30 @@
# Bug Report: task-status-reason
## Summary
Audit of status_reason implementation against SPEC.md found minor issues: a dead-code branch in the status_reason message, and a pre-existing REFEREE state that's never produced.
## Bugs Found
### Bug 1: Dead message branch in status_reason for BLOCKED state
- **Severity**: Low
- **Location**: `automaton/dashboard/core/task.py:149`
- **Description**: The message `"Verdict is empty or could not be parsed"` has two scenarios:
1. Empty verdict → reachable (content is `""`, correctly returns this message)
2. Unparseable verdict → unreachable. When `parse_verdict_status()` returns `None`, the state machine in `determine_task_state()` doesn't classify the task as BLOCKED — it falls through to earlier state checks. So a task is never both BLOCKED and "could not be parsed".
- **Suggested Fix**: Change message to `"Verdict is empty"` to accurately reflect the only reachable case.
### Bug 2: REFEREE state never produced by state machine
- **Severity**: Low
- **Location**: `automaton/dashboard/core/task.py:174` (fallback `status_reason` line), and `task.py:226-272` (determine_task_state)
- **Description**: `TaskState.REFEREE` exists in the enum and in the sort order, but `determine_task_state` never returns it. When a VERDICT.md is present but unparseable, the state machine falls through to earlier artifact checks instead of assigning REFEREE. This means the fallback status reason `"In referee phase"` is unreachable, and tasks with ambiguous verdicts silently show as earlier states (e.g., RESEARCH if only SPEC.md exists alongside an unparseable VERDICT.md).
- **Pre-existing**: This predates the task and is not introduced by the implementation, but the status_reason property exposes it because the REFEREE branch is dead code.
- **Suggested Fix**: Add `if "VERDICT.md" in artifacts: return TaskState.REFEREE, artifacts` after the terminal-state checks in `determine_task_state()`, before the state machine fallthrough.
### Bug 3: REFEREE status reason is generic
- **Severity**: Low
- **Location**: `automaton/dashboard/core/task.py:175`
- **Description**: The fallthrough line `return f"In {self.state.value} phase"` would produce generic messages like `"In blocked phase"` or `"In done phase"` for states that are handled above it. This is actually dead code for all defined states since every `TaskState` value is covered by an explicit `if` branch. If a new state is added without adding a status_reason handler, it gets a generic message rather than failing loudly.
- **Suggested Fix**: Replace the fallthrough with a clear signal: either raise an error, or explicitly list the catch to alert developers when adding states.
## Score
+5