Complete Relay review-gated Project workflow - #16
Merged
Conversation
…bservability, lifecycle)
…y (phase 6 review)
Backend (design doc §8 gaps closed):
- project_runs.started_at is now recorded on first dispatch via a
COALESCE-guarded db method; cleared on retry/partial-reexecute so
re-dispatch re-records a fresh timestamp.
- /v1/catalog/project-runs adds project_name, failed_node_id,
blocked_step_count, and started_at to every catalog item so the
GUI list does not need an N+1 fetch per row.
- /v1/project-runs/{id}/steps now returns attempt_count on each
step (project_step_runs COUNT subquery).
- resolve_step_inputs tags each resolved entry with from_node /
from_role so receipt resolved_inputs can render
'A1 <- pick(result)' in the inspector.
GUI Phase 1 (relay/gui/project_runs.py):
- New sidebar entry 'Project Runs' under Runs; project_runs
selection key; dedicated 2s polling timer (live Run selected
=> detail refresh, 5s list cadence, terminal Runs never polled).
- ProjectRunsView (master-detail) groups by Needs action
(failed / awaiting_approval) / Running / Completed
(date subgroup) / Cancelled; rows surface failed node name.
- ProjectRunDetailView renders a StatusBadge + one-line English
verdict, a sortable steps table with attempts/duration/worker,
approve/reject buttons for awaiting runs, and a final-artifact
strip with Open output folder action.
- _humanize_error copy for common error codes.
GUI Phase 2 (node inspector):
- ProjectRunInspectorView renders attempt history (receipt
task_runs), active Task Run summary with fallback worker note,
resolved inputs as 'A1 <- pick(result)', produced Artifacts
table, and node-level actions (Open logs / Open answer /
Re-execute from this node).
- Steps-table row selection drives the inspector; receipt,
/v1/jobs/{id}, /v1/jobs/{id}/artifacts are fanned out per step
on Run selection.
Regressions:
- tests/test_project_runs_backend.py (7 tests): started_at
lifecycle, catalog new fields, attempt_count, ensure_started
idempotency.
- tests/test_project_runs_gui.py (24 tests): grouping, filters,
verdict copy, steps table attempt column, awaiting approval
approve/reject, completed output folder, polling terminal vs
live, retry action uses failed_node_id, approve POST route,
inspector attempt history / inputs / outputs, action signals,
MainWindow receipt/detail/artifacts routing, re-execute from
node, open logs/answer navigation.
Quality gates:
- ruff format --check / ruff check on every changed file: clean.
- Full unittest: 573 tests pass (1 skip).
- python build_release.py -> relay.pyz 1.1.0 build succeeds.
Also includes the broader unstaged state from earlier sessions
(design grammar v1.1, profile/task_input support, additional
scripts, references, wiki updates) so this branch is the snapshot
needed to continue Project Runs phases 3-4 on another machine.
No main merge; pushed only to feat/phase0-domain-compat.
Phase 3 — Pipeline view (design doc §5 ⓑ-1): - New ProjectRunPipelineView lays out nodes in topological columns via _level_for_nodes (longest-path predecessor walk) and renders each node as a ProjectRunNodeCard: status icon + word + color, task name, duration / worker, retry badge (attempt_count > 1), and a humanized error line when the step failed. - Blocked descendants render dimmed with a dashed border; edges leaving failed steps render dashed (ProjectRunEdgeArrow) so the cause/effect of a failure is visible at a glance. - Clicking a card emits node_selected; the detail view syncs the steps table / inspector with the pipeline selection. Phase 4 — Timeline view (design doc §5 ⓑ-2): - New ProjectRunTimelineView + ProjectRunTimelineCanvas draw one bar per attempt; retries stack as separate rows on the same node, fan-outs read as parallel rows. - X axis is the run window from earliest started_at to latest completed_at with second resolution; an attempt without a completed_at extends to the latest known point so in-progress work is visible. Detail view integration: - ProjectRunDetailView replaces the standalone steps table with a Pipeline | Timeline | Steps tab widget; tab switching keeps the inspector selection in sync. Regressions: - tests/test_project_runs_gui.py gains 9 tests: _level_for_nodes longest-path layout, pipeline card rendering and click signal, blocked node styling, timeline attempt grouping, empty timeline state, timeline canvas paint with no timing data, detail view tab labels, pipeline node selection syncing the steps table, and tabs hidden when no Run is selected (33 total in this file). Quality gates: - ruff format --check / ruff check on every changed file: clean. - Full unittest: 582 tests pass (1 skip). - python build_release.py -> relay.pyz 1.1.0 build succeeds. memo.md and log.md updated: Project Runs screen Phases 1-4 all shipped; only edit-with-files approval and a resolve_step_inputs legacy backfill remain on the open list. Pushed only to feat/phase0-domain-compat; main is untouched.
… Project Runs view Project editor (relay/gui/projects.py, main_window.py): - Task selection is now a QComboBox keyed by task_id instead of a text cell requiring the user to hand-type "Name (task_id)". - Nodes/Connections/Outputs tables wrapped in a QScrollArea so Save/ Cancel can never be pushed off-screen by row growth. - Save no longer closes the dialog before the POST resolves: the daemon's real error_message (e.g. "Task not found: <id>") now surfaces in the still-open dialog with every typed row intact; the dialog only closes once the write is confirmed. - Connections/outputs node references are pickers built from the node_ids already typed above, instead of a second freehand field. - Removed duplicate _on_delete / _delivery_root_contains definitions. Codex adapter (relay/adapters/codex.py, request_builder.py, validation.py): - Fixed deep doctor PROCESS_CRASHED: the output-schema strictifier for OpenAI structured-output mode only fixed up the root object, so the nested artifacts.items.role property broke strict mode. Strictification is now recursive, with optional properties made nullable instead of forced, and validation accepts an explicit null role as undeclared. Project Runs GUI (relay/gui/project_runs.py): - Separated Pipeline/Steps/Timeline/Inspector responsibilities, fixed DAG edge geometry, added Worker evidence columns and toggle persistence, and replaced the Steps tab with a Task-grouped Artifacts Preview (structured JSON tree, format-aware rendering, final-output pinning, Pipeline double-click navigation). 626 tests pass (19 in test_phase4_gui.py, 6 new), Ruff clean. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Lets a Project attach an Orchestrator that narrates progress, repairs
step failures within a bounded budget (retry, worker swap, connection/
output role rebind, an append-only instruction addendum), and reports
the cause when it cannot. Authority is a strict subset of what a human
already does through the CLI/GUI and never leaves the Run; the
registered Project/Task definitions are never mutated. A deterministic
Tier 0 resolves what it can with zero LLM calls before an optional
Tier 1 LLM call (dispatched as an ordinary Task Run); any Orchestrator
failure falls back to today's deterministic behavior.
- Schema v14->v16: project_run_events, project_run_orchestrator_state,
step_overrides_json, ProjectSpec.orchestrator, Task.default_model.
- relay/orchestrator/: planner (Tier 0), agent (Tier 1), supervisor
(ladder + budget), narration, decision schema, override overlay.
- API/CLI: GET /v1/project-runs/{id}/orchestrator, relay project-run
orchestrator, relay project orchestrator-show/-set.
- GUI: Orchestrator tab on Project Runs, Orchestrator section in the
Project editor.
- Verified end to end on a real 3-node Project (Codex + Antigravity),
which surfaced and fixed three real bugs: worker-fallback carrying a
provider-specific model ID to a different provider, service-caller
target-path inference false-positives on Orchestrator prompt text,
and a deterministic JSON auto-repair for a real malformed nested
JSON-in-JSON escaping mistake (no LLM, two narrow unambiguous
patterns only).
789 tests and Ruff pass.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
miter37
marked this pull request as ready for review
August 11, 2026 11:57
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What changed
Validation
ruff check .— passedruff format --check .— passedpy -m unittest discover -s tests— 823 tests passed, 1 skippedThe local
.claude/settings.local.jsonremains uncommitted because it is machine-local permission configuration.