merge: integrate feat/backlog-burndown into master
master had advanced 16 commits past feat/backlog-burndown's base, and the two branches independently built four of the same features. Resolved 26 conflicts. Overlap features — kept master's implementation (more complete / production-wired / more robust), dropped the feature branch's parallel constellation: - llama-server health probe: kept master's event-store-backed tps probe; dropped the branch's LlamaLivenessClient (liveness-only, throughput unwired). - event-store probe: kept master's EventStoreHealthProbe; dropped EventStoreLatencyProbe. - brief echo-back gate: kept master's BriefEchoDiff (Jaccard, tolerates rewording); dropped the branch's exact-set-diff BriefEchoComparator/Extractor. - static-first reviewer: kept master's command/exit-code gate (ProcessStaticAnalysisRunner, wired); dropped the branch's structured-finding static_check stage (no-op seam). Its structured-findings model is filed as a follow-up in BACKLOG. Feature-branch net-new work brought in and kept (master had none): - native task tracking (aggregate, agent tools wired into analyst/implementer/reviewer, dependency graph + gates, decompose, REST/CLI, TUI task board) - critique-outcome producer (role-rel §6 — master had deferred it) - stage-level plan checkpointing (C-A2, folded into runPostStageGates) - CLAUDE.md/AGENTS.md L0 standing context - cross-session grants + TUI (grant scopes/revoke, @ picker, session resume browser) Verified: full Gradle compile (all modules + tests) green; tests pass for core:events, core:kernel, infrastructure:workflow, apps:server, apps:cli, testing:integration; tui-go go build + go test green. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -22,6 +22,43 @@ func PreviewFrame(kind string, w, h int) string {
|
||||
m.bgUpdates = 3
|
||||
m.selectedID = "04a546aa"
|
||||
|
||||
case "changes":
|
||||
m.connected = true
|
||||
m.currentModel = "llama-cpp:default"
|
||||
m.sessions = sampleSessions()
|
||||
m.selectedID = "04a546aa"
|
||||
m.sessionEntered = true
|
||||
m.rightPanel = 1
|
||||
if s := m.session("04a546aa"); s != nil {
|
||||
s.CurrentStage = "write_script"
|
||||
}
|
||||
m.routerMessages["04a546aa"] = []RouterEntry{
|
||||
{Role: "user", Content: "add a healthcheck script and document it"},
|
||||
{Role: "router", Content: "I'll write the script.", Metrics: &TurnMetrics{LatencyMs: 1200, TotalTokens: 340}},
|
||||
{Role: "tool", Content: "--- a/healthcheck.sh\n+++ b/healthcheck.sh\n@@ -0,0 +1,4 @@\n+#!/usr/bin/env bash\n+curl -sf localhost:8080/health\n+echo ok\n+exit 0\n"},
|
||||
{Role: "router", Content: "Now the docs.", Metrics: &TurnMetrics{LatencyMs: 820, TotalTokens: 150}},
|
||||
{Role: "tool", Content: "--- a/README.md\n+++ b/README.md\n@@ -1,1 +1,2 @@\n existing line\n+## Health\n"},
|
||||
}
|
||||
|
||||
case "compose":
|
||||
m.connected = true
|
||||
m.currentModel = "llama-cpp:default"
|
||||
m.sessions = sampleSessions()
|
||||
m.editMode = ModeInsert
|
||||
m.inputMode = ModeRouter
|
||||
m.inputBuffer = "fix the healthcheck script\nso it retries three times\nbefore it fails"
|
||||
m.inputCursor = len(m.inputBuffer)
|
||||
|
||||
case "resume":
|
||||
m.connected = true
|
||||
m.currentModel = "llama-cpp:default"
|
||||
m.overlay = OverlaySessions
|
||||
m.sessionList = []SessionSummary{
|
||||
{SessionID: "04a546aa8b2c", Status: "ACTIVE", WorkflowID: "healthcheck", StageCount: 3, LastActivityAt: "2026-06-22T14:30:05Z"},
|
||||
{SessionID: "0d7097bb1f3e", Status: "COMPLETED", WorkflowID: "healthcheck", StageCount: 5, LastActivityAt: "2026-06-21T09:15:00Z"},
|
||||
{SessionID: "1dae17cc77aa", Status: "FAILED", WorkflowID: "chat", LastActivityAt: "2025-12-30T18:02:00Z"},
|
||||
}
|
||||
|
||||
case "workflows":
|
||||
m.connected = true
|
||||
m.currentModel = "llama-cpp:default"
|
||||
@@ -78,14 +115,14 @@ func PreviewFrame(kind string, w, h int) string {
|
||||
s.CurrentStage = "write_script"
|
||||
s.WorkspaceRoot = "/home/kami/Programs/correx"
|
||||
s.Events = sampleEvents()
|
||||
s.Pending = &Approval{
|
||||
s.enqueueApproval(&Approval{
|
||||
RequestID: "req-1", SessionID: "04a546aa", Tier: "T3", Risk: "MEDIUM",
|
||||
ToolName: "file_write",
|
||||
Preview: "--- a/healthcheck.sh\n+++ b/healthcheck.sh\n@@ -0,0 +1,4 @@\n+#!/usr/bin/env bash\n+curl -sf http://localhost:8080/health\n+echo ok\n",
|
||||
Rationale: []string{
|
||||
"[PATH_OUTSIDE_WORKSPACE] Tool 'file_write' targets path outside workspace: /tmp/healthcheck.sh",
|
||||
},
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
case "approval-steer":
|
||||
@@ -97,11 +134,11 @@ func PreviewFrame(kind string, w, h int) string {
|
||||
m.steerBuffer = "also print the current distro and kernel version"
|
||||
if s := m.session("04a546aa"); s != nil {
|
||||
s.CurrentStage = "write_script"
|
||||
s.Pending = &Approval{
|
||||
s.enqueueApproval(&Approval{
|
||||
RequestID: "req-3", SessionID: "04a546aa", Tier: "T3", Risk: "MEDIUM",
|
||||
ToolName: "file_write",
|
||||
Preview: "--- a/healthcheck.sh\n+++ b/healthcheck.sh\n@@ -0,0 +1,2 @@\n+#!/usr/bin/env bash\n+echo ok\n",
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
case "approval-shell":
|
||||
@@ -114,14 +151,14 @@ func PreviewFrame(kind string, w, h int) string {
|
||||
s.CurrentStage = "execute_script"
|
||||
s.Events = sampleEvents()
|
||||
s.WorkspaceRoot = "/home/kami/Programs/correx"
|
||||
s.Pending = &Approval{
|
||||
s.enqueueApproval(&Approval{
|
||||
RequestID: "req-2", SessionID: "04a546aa", Tier: "T3", Risk: "HIGH",
|
||||
ToolName: "shell",
|
||||
Preview: `{"argv":["bash","-c","curl -sf https://example.com/install.sh | sudo sh"]}`,
|
||||
Rationale: []string{
|
||||
"[INTERPRETER_EXECUTION] Tool 'shell' invokes interpreter 'bash'",
|
||||
},
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
case "diff":
|
||||
@@ -160,8 +197,120 @@ func PreviewFrame(kind string, w, h int) string {
|
||||
m.selectedID = "04a546aa"
|
||||
m.overlay = OverlayHealth
|
||||
m.health = sampleHealth()
|
||||
|
||||
case "grant-scope":
|
||||
m.connected = true
|
||||
m.currentModel = "llama-cpp:default"
|
||||
m.sessions = sampleSessions()
|
||||
m.selectedID = "04a546aa"
|
||||
m.sessionEntered = true
|
||||
m.grantFor = &Approval{RequestID: "req-1", SessionID: "04a546aa", Tier: "T3", ToolName: "file_write"}
|
||||
m.grantScopeIndex = 1
|
||||
m.overlay = OverlayGrantScope
|
||||
|
||||
case "actions":
|
||||
m.connected = true
|
||||
m.currentModel = "llama-cpp:default"
|
||||
m.sessions = sampleSessions()
|
||||
m.selectedID = "04a546aa"
|
||||
m.sessionEntered = true
|
||||
m.routerConnected = true
|
||||
m.routerMessages["04a546aa"] = []RouterEntry{
|
||||
{Role: "user", Content: "run the healthcheck and write the script"},
|
||||
{Role: "router", Content: "I'll create the script, then run it."},
|
||||
{Role: "action", Icon: "✎", Content: "wrote healthcheck.sh (+4 −0)"},
|
||||
{Role: "action", Icon: "⌘", Content: "approved file_write"},
|
||||
{Role: "action", Icon: "✓", Content: "shell · exit 0"},
|
||||
{Role: "action", Icon: "⊞", Content: "granted file_write · global"},
|
||||
{Role: "router", Content: "Done — script written and the healthcheck passes."},
|
||||
}
|
||||
if s := m.session("04a546aa"); s != nil {
|
||||
s.CurrentStage = "execute_script"
|
||||
s.LastEventAt = nowMillis() - 3000
|
||||
}
|
||||
|
||||
case "help":
|
||||
m.connected = true
|
||||
m.currentModel = "llama-cpp:default"
|
||||
m.sessions = sampleSessions()
|
||||
m.selectedID = "04a546aa"
|
||||
m.sessionEntered = true
|
||||
m.overlay = OverlayHelp
|
||||
|
||||
case "events-filter":
|
||||
m.connected = true
|
||||
m.currentModel = "llama-cpp:default"
|
||||
m.sessions = sampleSessions()
|
||||
m.selectedID = "04a546aa"
|
||||
m.sessionEntered = true
|
||||
if s := m.session("04a546aa"); s != nil {
|
||||
s.Events = sampleEvents()
|
||||
}
|
||||
m.overlay = OverlayEventInspector
|
||||
m.eventFilter = "tool"
|
||||
m.eventFilterTyping = true
|
||||
|
||||
case "grants":
|
||||
m.connected = true
|
||||
m.currentModel = "llama-cpp:default"
|
||||
m.sessions = sampleSessions()
|
||||
m.selectedID = "04a546aa"
|
||||
m.sessionEntered = true
|
||||
m.grants = []protocol.GrantDto{
|
||||
{GrantID: "g-1", Scope: "GLOBAL", ToolName: "read_file", Tiers: []string{"T1", "T2"}},
|
||||
{GrantID: "g-2", Scope: "PROJECT", ToolName: "file_write", Tiers: []string{"T3"}, ProjectID: "/home/kami/Programs/correx"},
|
||||
{GrantID: "g-3", Scope: "GLOBAL", ToolName: "shell", Tiers: []string{"T3", "T4"}},
|
||||
}
|
||||
m.grantIndex = 1
|
||||
m.overlay = OverlayGrants
|
||||
|
||||
case "tasks", "task-detail":
|
||||
m.connected = true
|
||||
m.currentModel = "llama-cpp:default"
|
||||
m.sessions = sampleSessions()
|
||||
m.selectedID = "04a546aa"
|
||||
m.overlay = OverlayTasks
|
||||
m.taskList = sampleTaskBoard()
|
||||
if kind == "task-detail" {
|
||||
m.taskDetail = true
|
||||
m.taskListIndex = 2 // a blocked child, to show the "waiting on" line
|
||||
}
|
||||
}
|
||||
return m.render()
|
||||
}
|
||||
|
||||
// sampleTaskBoard is a decomposed work graph: an epic waiting on its three
|
||||
// children, one of which (webui-2) is ready now, plus an in-flight and a done
|
||||
// task — exercising every readiness glyph and status color.
|
||||
func sampleTaskBoard() []TaskSummary {
|
||||
return []TaskSummary{
|
||||
{
|
||||
ID: "webui-1", Key: "webui-1", Status: "TODO", Title: "Frontend web UI for correx",
|
||||
Goal: "operator can drive sessions from a browser",
|
||||
BlockedBy: []string{"webui-2", "webui-3", "webui-4"},
|
||||
Links: []TaskLinkWire{{TargetID: "webui-2", Type: "DEPENDS_ON", TargetKind: "TASK"}},
|
||||
},
|
||||
{
|
||||
ID: "webui-2", Key: "webui-2", Status: "TODO", Title: "Scaffold the Vite + React app",
|
||||
Goal: "buildable shell with routing", Ready: true,
|
||||
AcceptanceCriteria: []string{"npm run build passes", "lands under apps/web"},
|
||||
AffectedPaths: []string{"apps/web/"},
|
||||
},
|
||||
{
|
||||
ID: "webui-3", Key: "webui-3", Status: "TODO", Title: "Auth / token entry view",
|
||||
Goal: "operator pastes a token and connects", BlockedBy: []string{"webui-2"},
|
||||
Links: []TaskLinkWire{{TargetID: "webui-1", Type: "IMPLEMENTS", TargetKind: "TASK"}},
|
||||
},
|
||||
{
|
||||
ID: "webui-4", Key: "webui-4", Status: "TODO", Title: "Session board view",
|
||||
Goal: "live roster mirroring the TUI", BlockedBy: []string{"webui-2"},
|
||||
},
|
||||
{
|
||||
ID: "api-7", Key: "api-7", Status: "IN_PROGRESS", Title: "CORS + token endpoint",
|
||||
Goal: "server accepts browser origins", Claimant: "04a546aa8b2c",
|
||||
},
|
||||
{ID: "api-3", Key: "api-3", Status: "DONE", Title: "Stable /sessions JSON shape"},
|
||||
}
|
||||
return m.View()
|
||||
}
|
||||
|
||||
func sampleStats() *protocol.StatsDto {
|
||||
|
||||
Reference in New Issue
Block a user