v2.0: state enforcement, project scoping, harness integration
CI / build (push) Has been cancelled

State Enforcement (v2.0):
- .state file as single source of truth for task phase
- Approval gates for research, decomposition, design, test_design
- status.py --transition refuses illegal phase transitions
- status.py --validate-folder detects out-of-order artifacts
- status.py --audit checks all tasks for violations
- status.py --create-task is the only valid way to create tasks
- Pre-v2.0 tasks without .state are UNTRACKED -- all commands refuse them
- New --upgrade command bootstraps .state files for existing tasks

Project Scoping:
- --project flag added to all status.py commands across 16+ files
- _find_project_dir errors instead of silently falling back to ~/.automaton/
- --scope-check marks framework files OUT_OF_SCOPE when working on a project
- Dashboard handlers use stored project_root instead of re-detecting from CWD
- Prompts reference ~/.automaton/scripts/vram_detect.py (not {project}/.automaton/)

Harness Integration:
- status.py --can-edit now supports project-level checks (no --task required)
- --can-edit --file checks file scope without --task
- --json output for machine-readable harness integration
- opencode plugin (plugins/automaton-guard/plugin.ts) intercepts edit/write
- Git pre-commit hook (scripts/git-hooks/pre-commit) blocks commits without task
- Formal integration contract (contracts/harness-integration.md)

Other:
- upgrade.sh delegates to status.py --upgrade instead of manual heuristics
- Phase prompts reference --project {project} for multi-project scoping
- 200 tests passing (14 new)
This commit is contained in:
2026-06-15 14:16:46 -04:00
parent 79b783864e
commit 05c76852a2
151 changed files with 7295 additions and 632 deletions
+73
View File
@@ -3,7 +3,80 @@
## [unreleased]
### Added
- **Harness pre-edit hook**: `--can-edit` now supports project-level checks without `--task`, file scope checks with `--file`, and `--json` output for machine-readable harness integration
- **opencode plugin**: `plugins/automaton-guard/plugin.ts` — intercepts `edit` and `write` tool calls, calls `--can-edit` before allowing modifications
- **Git pre-commit hook**: `scripts/git-hooks/pre-commit` — blocks commits when no task is in an edit-allowed phase (universal safety net for all harnesses)
- **Pre-v2.0 task enforcement**: Tasks without `.state` files are UNTRACKED — `--transition`, `--can-edit`, `--task`, and `--approve` all refuse to operate on them
- **New `--upgrade` command**: Bootstraps `.state` files for pre-v2.0 tasks (single task with `--task` or all tasks at once)
- **Untracked task reporting**: `--list` shows `UNTRACKED (no .state)` for tasks without `.state` files instead of silently bootstrapping
- **Project scoping fix**: `status.py` errors when no project is detected instead of silently falling back to framework directory
- **Scope check fix**: `--scope-check` marks framework files as OUT_OF_SCOPE when working on a project
- **Dashboard scope fix**: Handler methods use stored `project_root` instead of re-detecting from CWD on every request
- **`--project` flag**: Added to all status.py command invocations across 16+ prompt and config files
- **`_infer_state_from_artifacts` locked to `--upgrade`**: Removed as silent fallback from all operational commands
- **Phase approval gates**: Research, Decomposition, Design, and Test Design phases now require explicit user approval (`:awaiting_approval` → `:approved`) before proceeding
- **status.py script**: Comprehensive enforcement and status tool with `--task`, `--list`, `--create-task`, `--transition`, `--approve`, `--validate-folder`, `--audit`, `--claim`, `--release`, `--next-available`, `--available`, `--can-edit`, `--scope-check`, `--same-session`, `--upgrade`
- **Untracked task enforcement**: Tasks without `.state` files are UNTRACKED — `--transition`, `--can-edit`, `--task`, `--approve` all refuse to operate on them. Run `--upgrade` to bootstrap `.state` files
- **`--project` flag**: All `status.py` commands now support `--project` for explicit project scoping when multiple projects exist on the same machine
- **`--upgrade` command**: Bootstraps `.state` files for pre-v2.0 tasks that lack them (single task with `--task` or all tasks at once)
- **Project scoping**: `status.py` now errors when not in a project directory and `--project` is not specified, instead of silently falling back to `~/.automaton/`
- **Scope check fix**: `--scope-check` now correctly marks framework files as OUT_OF_SCOPE when working on a project (was incorrectly always IN_SCOPE)
- **Dashboard scope fix**: Dashboard handler methods now use stored `project_root` and `scope` instead of re-detecting from CWD on every request
- **Phase-scoped prompts**: All phase prompts now include ALLOWED ACTIONS, FORBIDDEN ACTIONS, approval gates (where applicable), pre-work validation, and `.state` precondition checks
- **Orchestrator restructuring**: Reduced from 493 lines to 143 lines; sub-task management extracted to `subtask_management.md`; state machine reference moved to `workflow.md`
- **ALLOWED/FORBIDDEN enforcement**: Each phase prompt explicitly defines what agents can and cannot do, with user override resistance instructions
- **Workflow enforcement**: `--transition` refuses illegal phase transitions; `--validate-folder` detects out-of-order artifacts; `--audit` checks all tasks for violations
- **Task creation gate**: `status.py --create-task` is the only valid way to create tasks; `--audit` flags manually created folders
- **Approval log**: `.state.approvals` file records all user approvals with timestamp and approver
- **Multi-agent support**: Optional `Agent Configuration` section in `.agent.md` enables task claiming, role binding, and work discovery for multi-agent setups
- **Tool integration hooks**: `--can-edit`, `--scope-check`, `--same-session` for agent tool integrations (optional, not called by prompts)
- **upgrade.sh script**: Bootstraps `.state` files for existing tasks from artifact heuristic
- **Framework version marker**: `config.md` now includes version 2.0 with state enforcement indicator
### Changed
- **orchestrate.md**: Reduced from 493 to 143 lines; gate-check loop replaces soft advisory approach; approval gates enforced at research, decomposition, design, and test_design
- **workflow.md**: Rewritten to reference `.state` as canonical phase indicator; approval sub-states documented; enforcement via `status.py` documented
- **All phase prompts**: Added `.state` precondition check, pre-work validation, ALLOWED/FORBIDDEN sections, handling user overrides
- **research.md, design.md, decompose.md, test_design.md**: Added approval gate sections with `--transition {phase}:awaiting_approval` and `--approve`
- **implement.md, bug_finder.md, adversarial_bug_find.md, doc_review.md, referee.md**: Added no-approval-gate notes with direct `--transition` instructions
- `status_reason` property on Task model showing human-readable explanation for each state (#task-status-reason)
- Revoke buttons for approved/changes_requested reviews — replaces approve/request-changes with a single revoke option (#task-status-reason)
- pytest test suite covering dashboard core, app security, and VRAM detection (#add-pytest-test-suite)
- Structured verdict parsing: `parse_verdict_status()` uses `## Status:` line before substring fallback, preventing false-BLOCKED classification (#fix-verdict-parsing)
- State machine alignment: IMPLEMENTATION.md alone → Bug Find, ADVERSARIAL_BUG_REPORT alone → Bug Find (matching orchestrator spec) (#fix-verdict-parsing)
- Filesystem task name validation: `discover_tasks()` and `parse_sub_tasks()` skip directories with invalid characters (#fix-verdict-parsing)
- Added CORS headers, `do_OPTIONS` handler, `X-Content-Type-Options` to all dashboard API responses (#harden-dashboard-security)
- Added POST content-length bounds (64KB) and review comment length limits (4096 chars) (#harden-dashboard-security)
- Replaced inline `onclick` review handlers with `data-*` attributes and event delegation (#harden-dashboard-security)
- Applied `escapeHtml()` to task `display_name` in dashboard card rendering (#harden-dashboard-security)
- `GET /api/config` and `PUT /api/config` endpoints for reading and persisting dashboard configuration (#wire-dashboard-config)
- Server-side task cache with 1s TTL to eliminate redundant disk I/O on every polling request (#wire-dashboard-config)
- Dashboard JS applies config on init: theme, default_view, auto_refresh_interval, column_width, show_timelines (#wire-dashboard-config)
- Review POSTinvalidates task cache so next poll picks up changes (#wire-dashboard-config)
- `decomposition_content`, `parent_spec_content`, `vram_config_content` fields on `Task` model (#add-decomposition-content)
- `WaveGroup` dataclass and `parse_waves()` for extracting wave structure from DECOMPOSITION.md (#add-decomposition-content)
- `parse_vram_config()` for reading VRAM_CONFIG.md (#add-decomposition-content)
- Dashboard JS wave statistics use parsed wave data instead of 50/50 heuristic (#add-decomposition-content)
- Detail panel shows Decomposition, Parent Context, and VRAM Configuration sections (#add-decomposition-content)
### Changed
- Removed stale `dashboard = ["inotify>=0.2"]` optional dependency from pyproject.toml (#cleanup-cruft)
- Deleted `debug_root.py` stray development script (#cleanup-cruft)
- Deleted empty `automaton/dashboard/ui/widgets/` directory (#cleanup-cruft)
- Fixed `config.md` RAM detection description (was "via `free`", now "via `/proc/meminfo` or `sysctl`") (#cleanup-cruft)
- `_find_tasks_dir()` returns `Path` instead of `Path | None`, removed tautological condition (#cleanup-cruft)
- Removed `sys.path.insert` hack from `__main__.py` (#cleanup-cruft)
- Documented `scripts/dashboard.sh` convenience wrapper in README.md (#cleanup-cruft)
- Framework self-consistency test suite: 17 tests covering prompt stop conditions, hardcoded URLs, canonical paths, .rules.md sections, stale dependencies, CSS theme parity, verdict regression, and CI validation (#framework-self-consistency-tests)
### Fixed
- REFEREE state was never produced by state machine — verdict with unparseable status now correctly shows as REFEREE instead of silently falling through to earlier states (#task-status-reason)
- Pending review count in header now excludes done/blocked tasks (#task-status-reason)
- Critical: PASS verdicts mentioning FAIL/NEEDS_REVIEW in body text were falsely classified as BLOCKED (#fix-verdict-parsing)
- State divergence: IMPLEMENTATION.md alone showed "Implement" instead of "Bug Find" (#fix-verdict-parsing)
- Added mandatory stop conditions to `bug_finder.md` and `adversarial_bug_find.md` (#fix-prompt-consistency)
- Fixed deprecated `{project}/tasks/` path in `onboarding.md` (#fix-prompt-consistency)
- Expanded prompt path test to catch concrete deprecated path patterns (#fix-prompt-consistency)
- Root `pyproject.toml` with optional test/dashboard dependency groups (#add-pytest-test-suite)
- `AGENTS.md` with build/test commands and conventions (#developer-experience-gitea-ci)
- `.gitea/workflows/ci.yml` running py_compile, pytest, and shell script syntax checks (#developer-experience-gitea-ci)