- **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).
The review system (REVIEW.md, approve/changes_requested buttons,
review filter, review badges) was purely cosmetic — only the dashboard
read/wrote it. No workflow component (status.py, autopilot.py,
loop-runner.py, prompts) ever enforced it.
The 'Approve' button in the task detail panel confused users into
thinking it approved the task's phase gate. In reality it only wrote
to REVIEW.md, which had zero effect on transitions.
Removed:
- Review section (buttons, textarea, status badge) from detail panel
- Review badge from task cards
- Review filter from toolbar
- Pending-review counter from header
- All review-related CSS
Users now use the single '🔓 Approve Phase' button in the detail
panel, which calls status.py --approve and actually transitions the
task.
The dashboard had no way to run status.py --approve. The existing
'Approve' button only wrote to REVIEW.md (code review status), not
approve the task's phase gate.
Changes:
- /api/approve/{task_name} POST endpoint in app.py calls status.py --approve
- '🔓 Approve Phase' button in detail panel for approval-gated tasks
- approvePhase() JS function sends the POST and refreshes the board
- CSS for the new button (warning-yellow styling)
This enables the full automation flow: user clicks Approve Phase →
autopilot picks up the approved task on next tick → drives it forward.
--execute flag runs status.py --transition instead of printing suggestions.
--install-schedule creates a launchd plist that runs autopilot --drive --execute
every 60 seconds, providing full automation for task lifecycle transitions.
The autopilot loop:
- Runs on a schedule (60s default), ticks the most advanced unblocked task
- Stalls at :awaiting_approval gates until user runs --approve
- Handles all phases: new → research → decomposition → design → test_design →
implement → code_review → bug_find → adversarial_bug_find → doc_review →
referee → complete
- Fails cleanly when required artifacts are missing (agent must write them)
- Logs stdout/stderr to ~/.automaton/logs/autopilot-*.log
Also fixes test leak in scripts/automaton-cleanup.sh (pytest temp path was
being written into the real stub).
Replaced parent+subtask structure with 3 standalone tasks:
- mde-manifest-detection (foundational: models.json schema, detect_models.py)
- mde-interactive-enforcement (conflict matrix, --model args, audit, badges)
- mde-loop-enforcement (loop.json per-role model, {model} substitution, check-gate)
Parent archived to tasks/complete/ for history. Each task has its own
SPEC.md and is at research:awaiting_approval.
Rationale: subtasks are independently actionable with their own lifecycle.
Parent container added complexity without benefit.
runnable-test-suite (parent) — complete. Three sub-tasks all complete:
- make-tests-runnable: add requirements.txt pinning pytest==7.4.4, sweep all
docs/prompts from bare 'python' to 'python3' (stock macOS/Windows ships
python3), add idempotent .venv install block to scripts/install.sh, and add
'from __future__ import annotations' to 3 dashboard modules using PEP 604
union syntax at definition time so they import on Python 3.9+. The
PEP 604 bug was caught by the streak verifier itself during implementation.
- vram-detect-cross-platform: scripts/vram_detect.py now branches on
platform.system() for Linux/Darwin/Windows. macOS path uses
system_profiler SPDisplaysDataType (Apple Silicon unified memory via
sysctl hw.memsize; Intel Macs via 'VRAM (Total):'). Windows uses wmic
path win32_VideoController get AdapterRAM with PowerShell fallback. Linux
/proc/meminfo and nvidia-smi/lspci paths unchanged (regression test locks
them). Added 14 local-LLM context-window entries (llama-3.1, qwen2.5,
mistral, deepseek-r1/v3, glm-4/4.5, gemma-2, phi-3/4) with source-cited
model cards. Added _probe_ollama_model() that runs 'ollama list' as a
last-resort fallback. run_command() now wraps PowerShell cmdlets on
Windows (['powershell', '-NoProfile', '-NoLogo', '-Command', ...]).
- vram-detect-cross-platform-tests: 11 new monkeypatched tests in
tests/test_vram_detect.py covering Linux/Darwin/Windows branches for
detect_ram and detect_gpu_vram, prefix-match for unknown model names,
ollama probe, Windows PowerShell wrapper, and a LOCKED regression test
for _detect_ram_linux(). All external subprocess/sysctl/wmic calls are
mocked; no live hardware probes. Suite total: 235 passed, 0 errors.
Verified on this box: gpu_vram_gb 0 -> 32 on Apple M5 (32GB unified memory),
target context correctly jumped 12k -> 42k.
Subtask-2 implementation was authored by local LLM (gemma-4-26B-A4B-it
via headroom proxy @ localhost:8787). The 10-consecutive-clean-pass streak
verifier ran as the independent checker model (article #2/#9/#13 in
'WTF Is a Loop? Part 2'). One anti-spin rail fired: local LLM produced
inline branches where subtask-3 tests expected private _detect_ram_linux()
helper; extracted helper to match the test contract without weakening tests.
Parent + all 3 subtasks complete. Prior opencode-subagent implementation
of subtask-2 preserved in git stash for reference.