Restore archived tasks, fix dashboard scroll-reset, bind ornith, add Playwright smoke test

- **Restore 82 completed tasks** from tasks/complete/ back to tasks/ top
  level (all <7 days old per the cleanup policy; premature bulk archive
  was fixed).
- **Dashboard: fix scroll-reset on auto-refresh** — renderBoard rebuilds
  the board via innerHTML every 2s, destroying each column-body's
  scrollTop. Now snapshots column-body scrollTop + board.scrollLeft +
  view.scrollTop before rebuild and restores after (matched by
  PHASE_GROUPS index).
- **Dashboard UI additions** (pre-existing unstaged work): approval
  section cards, transition buttons, inline artifact editor (textarea for
  writing missing SPEC/VERDICT/etc from the detail modal).
- **Bind ornith as Implement model** — config.md: Model explicit to
  omlx/Ornith-1.0-35B-4bit-mlx, context window 32768. Interactive
  autopilot already used ornith via opencode default; now explicit.
- **Fix cleanup stub** — automaton-cleanup.sh had a stale --project arg
  pointing at a pytest temp dir (test isolation leak). Rewired to point
  at ~/.automaton.
- **Fix plist-isolation test** — test asserted host plist doesn't exist,
  but a real install creates it. Now snapshots mtime before run, asserts
  unchanged after (only a write during the test counts as bleed).
- **New Playwright smoke test** (tests/test_dashboard_ui.py) — 2 tests:
  board renders tasks, column scroll survives auto-refresh tick.
  Verified the test fails without the scroll fix (scrollTop resets to 0).
  Skipped via importorskip when playwright is absent (main CI stays
  green).
- **Clarify SI loop scope in README** — new-project onboarding section
  documents the framework-scoped self-improvement loop and options
  (leave/pause/create project loop).
- **CHANGELOG** documents all changes including the known model-divergence
  gap (mde tasks marked complete but per-role model binding was never
  implemented).
This commit is contained in:
Lap Tran
2026-06-26 10:05:18 -04:00
parent fe43b9e1fc
commit bc7daf8590
666 changed files with 15994 additions and 69 deletions
+1
View File
@@ -0,0 +1 @@
complete
@@ -0,0 +1,24 @@
# Implementation: Add Decomposition Content to Dashboard Data Model
## Summary
- Added `decomposition_content`, `parent_spec_content`, `vram_config_content` fields to `Task` dataclass
- Added `waves: list[WaveGroup]` field to `Task` dataclass
- Added `WaveGroup` dataclass with `wave_number`, `label`, `sub_task_names`
- Added `parse_waves()` function to extract wave structure from DECOMPOSITION.md content
- Added `parse_vram_config()` function to read VRAM_CONFIG.md
- `discover_tasks()` now loads all three new content fields and populates `waves` from decomposition
- `/api/tasks` and `/api/task/{name}` responses include `decomposition_content`, `parent_spec_content`, `vram_config_content`, and `waves`
- Dashboard JS uses parsed wave data for Wave 1/Wave 2 statistics (falls back to 50/50 heuristic when no wave data)
- Detail panel shows Decomposition, Parent Context, and VRAM Configuration sections when available
## Changes
- `automaton/dashboard/core/task.py`: Added `WaveGroup` dataclass, `parse_waves()`, `parse_vram_config()`, new fields on `Task`, population in `discover_tasks()`
- `automaton/dashboard/ui/app.py`: Added new fields to API responses
- `automaton/dashboard/html/dashboard.js`: Wave stats use parsed wave data, detail panel shows new content sections
- `tests/test_task.py`: Added `TestParseWaves` (4 tests), `TestDecompositionContent` (1 test), `TestParentSpecAndVramConfig` (3 tests)
## Test Results
134 passed in 0.10s
## Blockers
None
@@ -0,0 +1,4 @@
# Review
- **Status**: approved
- **Timestamp**: 2026-06-14T20:17:44.728863
- **Comment**:
+71
View File
@@ -0,0 +1,71 @@
# Add Decomposition Content to Dashboard Data Model
## Goal
Add missing content fields to the `Task` model so the dashboard can display wave structure from `DECOMPOSITION.md`, parent task context from `PARENT_SPEC.md`, and VRAM constraints from `VRAM_CONFIG.md`.
## Requirements
### R1. Add `decomposition_content` to Task model
`automaton/dashboard/core/task.py`: The `Task` dataclass has six content fields (`spec_content`, `verdict_content`, `bug_report_content`, `adversarial_bug_report_content`, `doc_review_content`, `design_content`) but no `decomposition_content`. This is the root cause of the dashboard's inability to parse wave structure from `DECOMPOSITION.md`.
**Fix**:
- Add `decomposition_content: Optional[str] = None` field to the `Task` dataclass (`task.py:77-90`)
- In `discover_tasks()` (`task.py:243-286`), load `DECOMPOSITION.md` content similar to how other artifacts are loaded
- Add `"decomposition_content"` to the `/api/tasks` response in `ui/app.py` `_serve_tasks()` and `_serve_task()`
### R2. Parse wave structure from DECOMPOSITION.md content
Currently `dashboard.js:278-285` splits sub-tasks into waves using a 50/50 heuristic (`half = Math.ceil(task.sub_tasks.length / 2)`), completely ignoring the actual wave definitions in `DECOMPOSITION.md`.
**Fix**:
- Parse wave headers from `decomposition_content` (Python side): extract `### Wave 1:` and `### Wave 2:` sections and their sub-task lists
- Store parsed wave data as `waves: list[WaveGroup]` on the `Task` model or as structured data in the API response
- Each wave group contains: wave number, label, sub-task names
- In `dashboard.js`, use parsed wave data instead of 50/50 heuristic for wave statistics
- Fall back to 50/50 heuristic only when `decomposition_content` is unavailable
### R3. Add `parent_spec_content` and `vram_config_content` to Task model
Sub-tasks have `PARENT_SPEC.md` and `VRAM_CONFIG.md` but these are not in the `ARTIFACTS` dict and not visible in the API response or detail panel. The detail panel cannot show parent context or VRAM constraints.
**Fix**:
- Add `parent_spec_content: Optional[str] = None` and `vram_config_content: Optional[str] = None` to `Task`
- Load these in `discover_tasks()` if the files exist
- Include in the API response
- Display in the detail panel when present (e.g., "Parent Context" and "VRAM Configuration" sections)
### R4. Add `WaveGroup` dataclass
Add a simple dataclass for wave metadata:
```python
@dataclass
class WaveGroup:
wave_number: int
label: str
sub_task_names: list[str]
```
### R5. Parse DECOMPOSITION.md wave sections
Add a `parse_waves(content: str) -> list[WaveGroup]` function that extracts wave definitions from `DECOMPOSITION.md` content. Pattern: `### Wave N: label` followed by lines starting with `- subtask-name`.
## Acceptance Criteria
- [ ] `Task` model has `decomposition_content`, `parent_spec_content`, `vram_config_content` fields
- [ ] `/api/tasks` response includes `decomposition_content` when present
- [ ] `/api/tasks` response includes `parent_spec_content` and `vram_config_content` when present
- [ ] `parse_waves()` correctly extracts wave structure from the template `DECOMPOSITION.md` in `templates/tasks/subtask-parent/`
- [ ] Dashboard JS uses parsed wave data for Wave 1/Wave 2 statistics instead of 50/50 split
- [ ] Detail panel shows "Parent Context" section when `parent_spec_content` exists
- [ ] Detail panel shows "VRAM Configuration" section when `vram_config_content` exists
- [ ] Existing tests pass
- [ ] New test: `parse_waves` with real DECOMPOSITION.md content
- [ ] New test: task with PARENT_SPEC.md and VRAM_CONFIG.md has content fields populated
## Non-Goals
- Not changing the DECOMPOSITION.md format
- Not applying VRAM constraints — display only
- Not modifying how sub-tasks are created or executed
@@ -0,0 +1,19 @@
# Verdict: add-decomposition-content
## Status: PASS
**Completion Date**: 2026-06-14
## Summary
Added decomposition_content, parent_spec_content, vram_config_content fields to Task model. Added WaveGroup dataclass and parse_waves() function for structured wave extraction from DECOMPOSITION.md. Dashboard JS wave stats now use parsed wave data instead of 50/50 heuristic. Detail panel shows new content sections for decomposition, parent context, and VRAM config.
## Findings
- All 134 tests pass (8 new)
- parse_waves correctly handles both `(label)` and `: label` wave header formats
- Falls back to 50/50 heuristic in JS when no wave data available
- Task model is backward compatible (new fields default to None)
## Tasks for Review / Tie-Breaks
- None
## Score
+10