feat(harness): dispatch /v1/harness/complete by harness kind (codex/opencode)
Adds an optional "harness" field so codex/opencode completions route to their own Usage readers instead of always assuming Claude's transcript format; unblocks the server side named as open in progress.md. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W1rkJ2hBMybnJctPbcy4tT
This commit is contained in:
+18
-1
@@ -260,6 +260,7 @@ func main() {
|
|||||||
}
|
}
|
||||||
var p struct {
|
var p struct {
|
||||||
TaskID string `json:"task_id"`
|
TaskID string `json:"task_id"`
|
||||||
|
Harness string `json:"harness"`
|
||||||
TranscriptPath string `json:"transcript_path"`
|
TranscriptPath string `json:"transcript_path"`
|
||||||
Report string `json:"report"`
|
Report string `json:"report"`
|
||||||
}
|
}
|
||||||
@@ -272,7 +273,23 @@ func main() {
|
|||||||
http.Error(w, "task not found", http.StatusNotFound)
|
http.Error(w, "task not found", http.StatusNotFound)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
usage, err := herdr.ClaudeUsage(p.TranscriptPath)
|
// Harness-specific session-state readers (AUDIT.md "Codex/opencode
|
||||||
|
// completion producers"). Same local-filesystem assumption B3 already
|
||||||
|
// made for Claude: the caller supplies the path to its own session
|
||||||
|
// state (transcript / rollout / message file), never a herdr pane id.
|
||||||
|
var usage herdr.Usage
|
||||||
|
var err error
|
||||||
|
switch p.Harness {
|
||||||
|
case "codex":
|
||||||
|
usage, err = herdr.CodexUsage(p.TranscriptPath)
|
||||||
|
case "opencode":
|
||||||
|
usage, err = herdr.OpenCodeUsage(p.TranscriptPath)
|
||||||
|
case "", "claude":
|
||||||
|
usage, err = herdr.ClaudeUsage(p.TranscriptPath)
|
||||||
|
default:
|
||||||
|
http.Error(w, "unknown harness: "+p.Harness, http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, "reading transcript: "+err.Error(), http.StatusBadRequest)
|
http.Error(w, "reading transcript: "+err.Error(), http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ if [ -f "$report_file" ]; then
|
|||||||
--arg task_id "$ORCHESTRA_TASK_ID" \
|
--arg task_id "$ORCHESTRA_TASK_ID" \
|
||||||
--arg transcript_path "$transcript_path" \
|
--arg transcript_path "$transcript_path" \
|
||||||
--arg report "$report" \
|
--arg report "$report" \
|
||||||
'{task_id: $task_id, transcript_path: $transcript_path, report: $report}')"
|
'{task_id: $task_id, harness: "claude", transcript_path: $transcript_path, report: $report}')"
|
||||||
|
|
||||||
if curl -fsS -X POST "${ORCHESTRA_URL%/}/v1/harness/complete" \
|
if curl -fsS -X POST "${ORCHESTRA_URL%/}/v1/harness/complete" \
|
||||||
-H "Content-Type: application/json" \
|
-H "Content-Type: application/json" \
|
||||||
|
|||||||
+20
-1
@@ -226,7 +226,26 @@ Fixed so far:
|
|||||||
it too). Both `TaskCreated` and `TaskAmended` now populate all four fields.
|
it too). Both `TaskCreated` and `TaskAmended` now populate all four fields.
|
||||||
Covered by `TestTaskAmendedAppliesAllFields` (`internal/store`).
|
Covered by `TestTaskAmendedAppliesAllFields` (`internal/store`).
|
||||||
|
|
||||||
Not yet started: Codex/opencode completion producers, S8–S11. See
|
- **Codex/opencode completion producers** — `/v1/harness/complete` was
|
||||||
|
Claude-only (hardcoded `herdr.ClaudeUsage`). Added an optional `harness`
|
||||||
|
field to the request body (`""`/`"claude"` unchanged default); `"codex"`
|
||||||
|
dispatches to `herdr.CodexUsage`, `"opencode"` to `herdr.OpenCodeUsage`,
|
||||||
|
anything else is a 400. Both readers already existed and were tested in
|
||||||
|
`internal/herdr` but had zero callers outside tests — same "written, not
|
||||||
|
wired" pattern the rest of this audit keeps finding. The Claude stop hook
|
||||||
|
(`deploy/hooks/orchestra-stop.sh`) now sends `"harness":"claude"`
|
||||||
|
explicitly for symmetry, no behavior change. **Not done:** an actual
|
||||||
|
Codex/opencode Stop-hook-equivalent script — Codex has no native stop hook
|
||||||
|
(would need a rollout-tail poller deciding when to call this), and
|
||||||
|
opencode's own turn-boundary mechanism is unverified from source (same
|
||||||
|
caveat AUDIT.md already names for Phase 2 item 4). This change unblocks
|
||||||
|
the server side; the harness-side wrapper for either is still open. No
|
||||||
|
new test: `cmd/orchestra` has zero handler test coverage of any kind
|
||||||
|
(pre-existing, confirmed by grep before writing this), so this follows the
|
||||||
|
existing pattern rather than introducing a one-off test harness for one
|
||||||
|
handler.
|
||||||
|
|
||||||
|
Not yet started: Codex/opencode Stop-hook-equivalent scripts, S8–S11. See
|
||||||
`AUDIT.md` for the full plan.
|
`AUDIT.md` for the full plan.
|
||||||
|
|
||||||
**Phase 0 done (2026-07-27):** this box has live TCP reachability to the real
|
**Phase 0 done (2026-07-27):** this box has live TCP reachability to the real
|
||||||
|
|||||||
Reference in New Issue
Block a user