From 33afb9d41cc92dd76517c943bdf575c2ef0d08c3 Mon Sep 17 00:00:00 2001 From: Meta Vens Date: Tue, 28 Apr 2026 12:14:04 +0100 Subject: [PATCH] Show MVP role lanes in status view --- README.md | 2 +- notes/epiphany-core-harness-surfaces.md | 7 +- notes/epiphany-fork-implementation-plan.md | 7 +- notes/fresh-workspace-handoff.md | 2 +- state/evidence.jsonl | 1 + state/map.yaml | 4 +- tools/epiphany_mvp_status.py | 92 +++++++++++++++++++++- tools/epiphany_mvp_status_smoke.py | 10 +++ 8 files changed, 114 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 236f31af..66d3c809 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ The current spine is real, not aspirational: - read-only CRRC next-action recommendations through `thread/epiphany/crrc` - live bound-job progress notifications through `thread/epiphany/jobsUpdated` - read-only reflection surfaces through `thread/epiphany/scene`, `jobs`, `freshness`, `context`, `pressure`, and `reorient` -- a first dogfood CLI operator view through `tools/epiphany_mvp_status.py` +- a first dogfood CLI operator view through `tools/epiphany_mvp_status.py`, including explicit implementation, modeling/checkpoint, verification/review, and reorientation lanes - durable investigation checkpointing for compaction-safe planning - repo-owned heavy Epiphany organs in `epiphany-core/`, with vendored Codex kept as the host seam where practical diff --git a/notes/epiphany-core-harness-surfaces.md b/notes/epiphany-core-harness-surfaces.md index ee242755..0b5533cf 100644 --- a/notes/epiphany-core-harness-surfaces.md +++ b/notes/epiphany-core-harness-surfaces.md @@ -59,7 +59,7 @@ The rule is: | `thread/epiphany/pressure` | read-only reflection | landed, live-smoked | Context-pressure gauge derived from token telemetry and recorded auto-compact/context limits. | | `thread/epiphany/reorient` | read-only policy reflection | landed, live-smoked | Bounded CRRC reorientation verdict derived from checkpoint, freshness, watcher, and pressure signals; returns resume vs regather without acting on the decision. | | `thread/epiphany/crrc` | read-only coordinator reflection | landed, live-smoked | Composes pressure, reorientation verdict, bound worker status/result, and available actions into one recommendation without launching, accepting, compacting, or mutating state. | -| `tools/epiphany_mvp_status.py` | operator CLI | landed, live-smoked | Starts or reads a thread through app-server and renders scene, pressure, reorient, jobs, result, and CRRC recommendation as a compact dogfood view. | +| `tools/epiphany_mvp_status.py` | operator CLI | landed, live-smoked | Starts or reads a thread through app-server and renders scene, pressure, reorient, jobs, result, CRRC recommendation, and MVP role lanes as a compact dogfood view. | ## Write Authority @@ -237,8 +237,9 @@ source of truth. The little tyrant remains theoretical, for now. The first dogfood operator view is landed as `tools/epiphany_mvp_status.py`. It starts or reads one thread through the app-server and prints the scene, pressure, reorientation verdict, jobs, reorient result, and CRRC recommendation -as a compact status report, with raw JSON available when needed. It is a window, -not a source of truth. +as a compact status report, with raw JSON available when needed. It also derives +the four MVP role lanes: implementation, modeling/checkpoint, verification/review, +and reorientation. It is a window, not a source of truth. The first live bound-runtime progress notification is also landed as `thread/epiphany/jobsUpdated`. It rides existing `agent_job_progress:{json}` diff --git a/notes/epiphany-fork-implementation-plan.md b/notes/epiphany-fork-implementation-plan.md index 3fe7c119..7932379d 100644 --- a/notes/epiphany-fork-implementation-plan.md +++ b/notes/epiphany-fork-implementation-plan.md @@ -177,9 +177,10 @@ The read-back, acceptance, coordinator, and first dogfood-view blockers are now landed as `thread/epiphany/reorientResult`, `thread/epiphany/reorientAccept`, `thread/epiphany/crrc`, and `tools/epiphany_mvp_status.py`. The next MVP blocker is richer role ownership: a human can now ask the harness what it -believes and what it recommends without reading Rust, but implementation, -modeling/checkpoint maintenance, and verification/review are still only narrow -roles rather than a reusable specialist registry. +believes and what it recommends without reading Rust, and the operator view now +shows implementation, modeling/checkpoint maintenance, verification/review, and +reorientation as distinct lanes. Those lanes are still derived views rather +than a reusable specialist registry. ## Phase 6 Direction diff --git a/notes/fresh-workspace-handoff.md b/notes/fresh-workspace-handoff.md index 03a5bfea..b7c04ce7 100644 --- a/notes/fresh-workspace-handoff.md +++ b/notes/fresh-workspace-handoff.md @@ -29,7 +29,7 @@ Do not trust this file for the exact live HEAD. Always check git. - Do not copy exact branch or HEAD from this note. Run `git status --short --branch` and `git log --oneline -5`. - Phase 1 through Phase 5 are complete enough. - Phase 6 has read-only `thread/epiphany/scene`, `thread/epiphany/jobs`, `thread/epiphany/freshness`, `thread/epiphany/context`, `thread/epiphany/pressure`, `thread/epiphany/reorient`, `thread/epiphany/crrc`, and `thread/epiphany/reorientResult`; durable `jobBindings` now act as a thin Epiphany-owned launcher seam with launcher id, authority scope, and backend kind/job id, `thread/epiphany/jobLaunch` / `thread/epiphany/jobInterrupt` now provide explicit bounded authority over that seam, jobs can overlay it onto live runtime `agent_jobs` progress for loaded threads, and `thread/epiphany/jobsUpdated` now translates live `agent_job_progress:{json}` background events into changed launcher-bound notifications without polling or scheduling. Freshness carries watcher-backed invalidation inputs, reorient turns checkpoint plus freshness/pressure/watcher signals into a read-only resume-versus-regather verdict, `thread/epiphany/reorientLaunch` is the first explicit runtime consumer over that verdict, `thread/epiphany/reorientResult` reads the launched worker output back as a reviewable finding without mutation or promotion, `thread/epiphany/reorientAccept` explicitly banks completed findings into accepted observation/evidence plus optional scratch/checkpoint state, and `thread/epiphany/crrc` recommends the next explicit CRRC action without launching, accepting, compacting, scheduling, or mutating. -- `tools/epiphany_mvp_status.py` is the first dogfood operator view. It starts or reads a thread through app-server and prints scene, pressure, reorient, jobs, reorient result, and CRRC recommendation as text or JSON. +- `tools/epiphany_mvp_status.py` is the first dogfood operator view. It starts or reads a thread through app-server and prints scene, pressure, reorient, jobs, reorient result, CRRC recommendation, and MVP role lanes as text or JSON. - Durable in-flight investigation checkpointing is now landed in authoritative typed state, writable through `thread/epiphany/update` or accepted `thread/epiphany/promote`, rendered into the prompt, and reflected through scene/context. - The repo is an Epiphany fork of Codex, not a Codex preset. - `vendor/codex` is tracked directly, not a submodule. diff --git a/state/evidence.jsonl b/state/evidence.jsonl index 601dae40..ed8443f5 100644 --- a/state/evidence.jsonl +++ b/state/evidence.jsonl @@ -52,3 +52,4 @@ {"ts": "2026-04-28T10:27:16+00:00", "type": "verification", "status": "ok", "note": "Phase 6 thread/epiphany/reorientAccept landed as the explicit acceptance write after reorientResult. It requires a completed reorient-worker backend result, appends accepted observation/evidence records, optionally updates scratch and investigation checkpoint state, and emits stateUpdated with source reorientAccept without accepting pending work, auto-promoting arbitrary worker output, launching follow-up jobs, or silently continuing. Focused protocol/app-server tests, schema fixture regeneration/checks, app-server build, and tools/epiphany_phase6_reorient_launch_smoke.py passed with launch, read-back, and acceptance assertions."} {"ts": "2026-04-28T11:01:36+00:00", "type": "implementation", "status": "ok", "note": "Landed read-only thread/epiphany/crrc coordinator recommendation over pressure, reorient verdict, fixed reorient-worker status/result, and available actions; focused protocol/app-server tests, schema fixtures, app-server build, cargo check, and live reorient-launch smoke verified the coordinator loop without adding scheduling or hidden mutation."} {"ts": "2026-04-28T11:08:09+00:00", "type": "implementation", "status": "ok", "note": "Landed tools/epiphany_mvp_status.py as the first dogfood operator view over scene, pressure, reorient, jobs, reorient-result, and CRRC recommendation; epiphany_mvp_status_smoke.py verifies cold-start missing-state rendering and CRRC regather recommendation through the live app-server."} +{"ts": "2026-04-28T11:13:43+00:00", "type": "implementation", "status": "ok", "note": "Extended the MVP status view with derived implementation, modeling/checkpoint, verification/review, and reorientation lanes over existing app-server signals; the status smoke now asserts the four role lanes and rendered operator section."} diff --git a/state/map.yaml b/state/map.yaml index ba1b979d..3bfaa478 100644 --- a/state/map.yaml +++ b/state/map.yaml @@ -82,7 +82,7 @@ accepted_design: - `thread/epiphany/pressure` is the first read-only context-pressure surface: it derives pressure from token telemetry and auto-compact/context limits without compacting, scheduling, mutating, or notifying. - `thread/epiphany/reorient` is the first bounded CRRC policy surface: it derives a read-only `resume` versus `regather` verdict from checkpoint, freshness, watcher, and pressure signals without mutating state, compacting, scheduling, or silently continuing work. - `thread/epiphany/crrc` is the first bounded CRRC coordinator recommendation surface: it composes pressure, the reorientation verdict, fixed reorient-worker binding/result status, finding read-back, and available actions into one read-only recommendation without launching, accepting, compacting, scheduling, or mutating state. - - `tools/epiphany_mvp_status.py` is the first dogfood operator view: it starts or reads a thread through app-server and renders scene, pressure, reorient, jobs, reorient result, and CRRC recommendation as text or JSON without becoming a state store. + - `tools/epiphany_mvp_status.py` is the first dogfood operator view: it starts or reads a thread through app-server and renders scene, pressure, reorient, jobs, reorient result, CRRC recommendation, and MVP role lanes as text or JSON without becoming a state store. - `thread/epiphany/reorientLaunch` is the first bounded runtime consumer over the reorientation verdict: it launches one fixed `reorient-worker` job through the existing job-control seam with explicit resume-versus-regather scope, authority, and checkpoint-derived payload, without making `thread/epiphany/reorient` a writer or turning CRRC into an ambient scheduler. - `thread/epiphany/reorientResult` is the first bounded read-back surface for that worker: it reads the fixed or requested reorient-worker binding through the current `agent_jobs` backend and projects completed output as a reviewable finding without mutation, promotion, scheduling, or hidden continuation. - `thread/epiphany/reorientAccept` is the first explicit acceptance write for completed reorient-worker findings: it appends accepted observation/evidence records, can optionally update scratch and investigation checkpoint state, and emits `stateUpdated` with source `reorientAccept` without accepting pending work or launching follow-up work. @@ -139,5 +139,5 @@ rejected_paths: reason: persistent state that accumulates every local truth becomes memory cruft and weakens rehydration current_status: - summary: Phase 1 durable state, Phase 2 prompt integration, Phase 3 typed read, Phase 4 retrieval/indexing, Phase 5 update/distill/propose/promote/read/notification, and Phase 6 read-only scene, jobs, freshness, targeted context, context-pressure reflection, watcher-backed invalidation inputs, durable investigation checkpointing, bounded CRRC reorientation policy, read-only CRRC coordinator recommendation, first dogfood operator status view, live bound-job progress notifications, a thin launcher seam in durable `job_bindings`, explicit `thread/epiphany/jobLaunch` / `thread/epiphany/jobInterrupt` authority over that seam, bounded `thread/epiphany/reorientLaunch`, read-only `thread/epiphany/reorientResult`, and explicit `thread/epiphany/reorientAccept` are landed. `job_bindings` now carry Epiphany-owned launcher metadata such as launcher id, authority scope, and backend kind/job id, while still tolerating the older runtime-agent-job pointer as a compatibility alias. `thread/epiphany/jobs` overlays that launcher seam onto real runtime `agent_jobs` progress for bound work, including runtime/backend job id, worker thread ids, and progress counts, without becoming a scheduler. `thread/epiphany/jobsUpdated` now translates runtime `agent_job_progress:{json}` background events into changed launcher-bound payloads only when the mapped job state actually changes, so clients can watch real owners move without polling the jobs read surface. The launch/interrupt control path still uses direct state-runtime fallback when a loaded ephemeral thread does not already carry a live sqlite handle, so authoritative bindings and runtime snapshots stay aligned instead of pretending the backend vanished. `thread/epiphany/reorient` consumes checkpoint, freshness, watcher, and pressure signals to return a read-only `resume` versus `regather` verdict with explicit checkpoint-path/frontier reasons. `thread/epiphany/crrc` composes pressure, that verdict, the fixed reorient-worker binding/result, finding read-back, and available actions into a read-only recommendation such as continue, prepare checkpoint, launch worker, wait, review, accept, or regather manually without launching, accepting, compacting, scheduling, or mutating. `tools/epiphany_mvp_status.py` starts or reads a thread through app-server and renders scene, pressure, reorient, jobs, reorient result, and CRRC recommendation as text or JSON without becoming a state store. `thread/epiphany/reorientLaunch` explicitly launches one fixed `reorient-worker` job with resume-or-regather scope, checkpoint-derived payload, and bounded structured output expectations. `thread/epiphany/reorientResult` reads that worker output back from the current `agent_jobs` backend as a reviewable finding with mode, summary, next safe move, checkpoint validity, inspected files, frontier ids, evidence ids, raw result, and errors, without mutating state, promoting evidence, scheduling work, or silently continuing. `thread/epiphany/reorientAccept` requires a completed worker result, appends accepted observation/evidence records, can explicitly update scratch and investigation checkpoint state, and emits `stateUpdated` with source `reorientAccept` without accepting pending work, auto-promoting arbitrary output, or launching follow-up work. Focused protocol/app-server tests, schema fixture regeneration/checks, app-server build, the live reorient-launch smoke, and the MVP status smoke cover the launch/read-back/accept/coordinator/operator seam. Investigation checkpoints still live in authoritative typed state, flow through the prompt, and reflect through scene/context without adding a second writer or fake scheduler. Persistent state was cut down so map, handoff, plan, harness surfaces, scratch, and evidence each carry one job instead of becoming a Jenga tower; evidence is now a distilled ledger rather than an activity feed. The global AGENTS Epiphany core command says persistent state is the agent's mind and explicitly permits the agent to ask for self-modification when memory or workflow makes it worse. The continuity goal is to bank the fire before the dark so compaction becomes less like death and more like sleep. + summary: Phase 1 durable state, Phase 2 prompt integration, Phase 3 typed read, Phase 4 retrieval/indexing, Phase 5 update/distill/propose/promote/read/notification, and Phase 6 read-only scene, jobs, freshness, targeted context, context-pressure reflection, watcher-backed invalidation inputs, durable investigation checkpointing, bounded CRRC reorientation policy, read-only CRRC coordinator recommendation, first dogfood operator status view with MVP role lanes, live bound-job progress notifications, a thin launcher seam in durable `job_bindings`, explicit `thread/epiphany/jobLaunch` / `thread/epiphany/jobInterrupt` authority over that seam, bounded `thread/epiphany/reorientLaunch`, read-only `thread/epiphany/reorientResult`, and explicit `thread/epiphany/reorientAccept` are landed. `job_bindings` now carry Epiphany-owned launcher metadata such as launcher id, authority scope, and backend kind/job id, while still tolerating the older runtime-agent-job pointer as a compatibility alias. `thread/epiphany/jobs` overlays that launcher seam onto real runtime `agent_jobs` progress for bound work, including runtime/backend job id, worker thread ids, and progress counts, without becoming a scheduler. `thread/epiphany/jobsUpdated` now translates runtime `agent_job_progress:{json}` background events into changed launcher-bound payloads only when the mapped job state actually changes, so clients can watch real owners move without polling the jobs read surface. The launch/interrupt control path still uses direct state-runtime fallback when a loaded ephemeral thread does not already carry a live sqlite handle, so authoritative bindings and runtime snapshots stay aligned instead of pretending the backend vanished. `thread/epiphany/reorient` consumes checkpoint, freshness, watcher, and pressure signals to return a read-only `resume` versus `regather` verdict with explicit checkpoint-path/frontier reasons. `thread/epiphany/crrc` composes pressure, that verdict, the fixed reorient-worker binding/result, finding read-back, and available actions into a read-only recommendation such as continue, prepare checkpoint, launch worker, wait, review, accept, or regather manually without launching, accepting, compacting, scheduling, or mutating. `tools/epiphany_mvp_status.py` starts or reads a thread through app-server and renders scene, pressure, reorient, jobs, reorient result, CRRC recommendation, and derived implementation/modeling/verification/reorientation role lanes as text or JSON without becoming a state store. `thread/epiphany/reorientLaunch` explicitly launches one fixed `reorient-worker` job with resume-or-regather scope, checkpoint-derived payload, and bounded structured output expectations. `thread/epiphany/reorientResult` reads that worker output back from the current `agent_jobs` backend as a reviewable finding with mode, summary, next safe move, checkpoint validity, inspected files, frontier ids, evidence ids, raw result, and errors, without mutating state, promoting evidence, scheduling work, or silently continuing. `thread/epiphany/reorientAccept` requires a completed worker result, appends accepted observation/evidence records, can explicitly update scratch and investigation checkpoint state, and emits `stateUpdated` with source `reorientAccept` without accepting pending work, auto-promoting arbitrary output, or launching follow-up work. Focused protocol/app-server tests, schema fixture regeneration/checks, app-server build, the live reorient-launch smoke, and the MVP status smoke cover the launch/read-back/accept/coordinator/operator seam. Investigation checkpoints still live in authoritative typed state, flow through the prompt, and reflect through scene/context without adding a second writer or fake scheduler. Persistent state was cut down so map, handoff, plan, harness surfaces, scratch, and evidence each carry one job instead of becoming a Jenga tower; evidence is now a distilled ledger rather than an activity feed. The global AGENTS Epiphany core command says persistent state is the agent's mind and explicitly permits the agent to ask for self-modification when memory or workflow makes it worse. The continuity goal is to bank the fire before the dark so compaction becomes less like death and more like sleep. next_action: Continue toward the MVP by adding the smallest role-scoped specialist ownership layer that makes implementation, modeling/checkpoint maintenance, and verification/review visible as distinct lanes without building a marketplace or hidden scheduler. Automatic broad specialist scheduling remains future work; do not restart the completed pressure, freshness, watcher-invalidation, investigation-checkpoint, reorientation, crrc, mvp-status, jobs-binding, jobsUpdated, thin-launcher-seam, job-control, reorient-launch, reorient-result, or reorient-accept slice unless a concrete regression appears. diff --git a/tools/epiphany_mvp_status.py b/tools/epiphany_mvp_status.py index 91a579eb..aa9daaeb 100644 --- a/tools/epiphany_mvp_status.py +++ b/tools/epiphany_mvp_status.py @@ -44,6 +44,83 @@ def job_summary(job: dict[str, Any]) -> str: ) +def job_by_id(jobs: list[dict[str, Any]], job_id: str) -> dict[str, Any] | None: + for job in jobs: + if job.get("id") == job_id: + return job + return None + + +def derive_role_lanes(status: dict[str, Any]) -> list[dict[str, str]]: + scene = status["scene"]["scene"] + pressure = status["pressure"]["pressure"] + reorient = status["reorient"]["decision"] + jobs = status["jobs"]["jobs"] + result = status["reorientResult"] + recommendation = status["crrc"]["recommendation"] + checkpoint = scene.get("investigationCheckpoint") or {} + verification = job_by_id(jobs, "verification") + + implementation_status = "ready" + implementation_note = "Continue the bounded coding task." + if recommendation["action"] != "continue": + implementation_status = "blocked" + implementation_note = f"Wait for CRRC action: {recommendation['action']}." + + modeling_status = "ready" if checkpoint else "needed" + modeling_note = ( + f"{checkpoint.get('disposition', 'checkpoint missing')}: " + f"{checkpoint.get('nextAction') or reorient['nextAction']}" + ) + + verification_status = verification.get("status", "unknown") if verification else "unknown" + if verification: + verification_note = ( + verification.get("blockingReason") + or verification.get("progressNote") + or "Review evidence and accepted findings before promotion." + ) + else: + verification_note = "Verification lane is unavailable." + + reorientation_status = recommendation["action"] + reorientation_note = ( + f"{reorient['action']} verdict, result {result['status']}, " + f"pressure {pressure['level']}." + ) + + return [ + { + "id": "implementation", + "title": "Implementation", + "status": implementation_status, + "owner": "coding-agent", + "note": implementation_note, + }, + { + "id": "modeling", + "title": "Modeling / Checkpoint", + "status": modeling_status, + "owner": "epiphany-modeler", + "note": modeling_note, + }, + { + "id": "verification", + "title": "Verification / Review", + "status": verification_status, + "owner": "epiphany-verifier", + "note": verification_note, + }, + { + "id": "reorientation", + "title": "Reorientation", + "status": reorientation_status, + "owner": "epiphany-reorient", + "note": reorientation_note, + }, + ] + + def collect_status( client: AppServerClient, *, @@ -68,7 +145,7 @@ def collect_status( reorient_result = client.send("thread/epiphany/reorientResult", {"threadId": thread_id}) crrc = client.send("thread/epiphany/crrc", {"threadId": thread_id}) - return { + status = { "threadId": thread_id, "read": read, "scene": scene, @@ -78,6 +155,8 @@ def collect_status( "reorientResult": reorient_result, "crrc": crrc, } + status["roleLanes"] = derive_role_lanes(status) + return status def render_status(status: dict[str, Any]) -> str: @@ -120,6 +199,17 @@ def render_status(status: dict[str, Any]) -> str: ] ) + lines.extend( + [ + "", + "Role Lanes", + ] + ) + for lane in status["roleLanes"]: + lines.append( + f"- {lane['title']}: {lane['status']} ({lane['owner']}) - {lane['note']}" + ) + lines.extend( [ "", diff --git a/tools/epiphany_mvp_status_smoke.py b/tools/epiphany_mvp_status_smoke.py index 9bd1d629..bec1e84f 100644 --- a/tools/epiphany_mvp_status_smoke.py +++ b/tools/epiphany_mvp_status_smoke.py @@ -63,10 +63,20 @@ def run_smoke(args: argparse.Namespace) -> dict[str, object]: "regatherManually" in rendered, "rendered status should expose the CRRC recommendation", ) + lane_ids = [lane["id"] for lane in status["roleLanes"]] + require( + lane_ids == ["implementation", "modeling", "verification", "reorientation"], + "status view should expose the four MVP role lanes", + ) + require( + "Role Lanes" in rendered and "Verification / Review" in rendered, + "rendered status should expose the role lane section", + ) result = { "threadId": status["threadId"], "recommendation": status["crrc"]["recommendation"], + "roleLanes": status["roleLanes"], "stateStatus": status["scene"]["scene"]["stateStatus"], "availableActions": status["scene"]["scene"]["availableActions"], "rendered": rendered,