Delete Design A, the harness-hook completion path, and retired deploy files
Acts on the seven review comments on PR #1. Design A is gone (comment 4). clients/ deleted rather than tracked: with workers carrying cross-machine work the bridge is undeployed, which supersedes the 2026-07-27 "keep through Phase 5" decision. CLAUDE.md, AGENTS.md and AUDIT.md updated from "retained" to "deleted". The harness-hook completion path is gone (comment 10). Investigation of the live OpenCode QA run showed orchestra-worker owns completion end to end: it watches for .orchestra/done, confirms via AgentStatus that the agent is not busy, then posts through /v1/federation/* with both lease epoch and expected version. The hook scripts used a different, older convention (.orchestra-report.md) and posted to /v1/harness/complete, which had already been reduced to a 410 stub - so that path could not have completed a task. Nothing exercised it, because the live run never used it. Deleted: the three deploy/hooks scripts, the 410 route, the unmounted harnessCompletion handler, and its test. That test passed against a handler no mux routed to, which is the exact "looks wired but isn't" pattern CLAUDE.md warns about; the constant-time token compare added to it earlier today goes with it, having never been reachable. /v1/harness/turn is untouched and still live. Retired deployment files (comments 8, 12, 14): deploy/orchestra.service and deploy/redeploy.sh (which sudo-installed to /usr/local/bin and restarted that unit), plus deploy/docker-api-entrypoint.sh. The entrypoint was safe to remove once its premise was checked: env vars reach the container through `env_file: .env` in compose.yaml, not by sourcing /etc/orchestra/orchestra.env - only config.jsonc is bind-mounted there - and Dockerfile.api's line 17 already sets ORCHESTRA_DATA/ORCHESTRA_PORT. Dockerfile.api now execs /app/orchestra directly. orchestra-worker.service is a different, current unit and is kept. deploy/config.example.json deleted as a duplicate (comment 6); the annotated .jsonc is the one registry.go points at, and its header no longer tells the reader to copy the file that just went away. Documentation corrected beyond the deletions: - CLAUDE.md's deployment section claimed the container bind-mounts /etc/orchestra:ro and its entrypoint sources the env file. Both wrong. - AGENTS.md still described a systemd deployment on homesrv as of 2026-07-27. - AUDIT.md's H5 row still described a "retained compatibility handler". - deploy/DEPLOYMENT.md still named redeploy.sh as the deployment path. - deploy/orchestra.env.example still cited EnvironmentFile=. TOKEN_MINIMAL_WORKFLOW_PLAN.md (comment 2) is untouched: it and WEB_UI_PLAN.md were both missed by REVIEW.md's documentation sweep, and reconciling a 534-line forward-looking plan against AUDIT.md is its own task, not a review fixup. Verified: go build ./..., go vet ./..., go test ./... all pass after the deletions, and go list ./... has no node_modules entry. No live herdr or pane was touched; nothing was deployed. The running image still predates this commit until compose is rebuilt. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GEugbHVYfAXFpTqDYbByEB
This commit is contained in:
@@ -1,19 +1,12 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"orchestra/internal/authz"
|
||||
"orchestra/internal/domain"
|
||||
"orchestra/internal/registry"
|
||||
"orchestra/internal/store"
|
||||
)
|
||||
|
||||
type unreachable struct{}
|
||||
@@ -55,75 +48,6 @@ func TestCoordinatorOwnsOnlyLocalHerdrInFederationMode(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestHarnessCompletionBuildsReceiptAndQuotaFromTranscript(t *testing.T) {
|
||||
s, err := store.Open(t.TempDir())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := s.Append(domain.Event{ID: domain.NewID(), Type: "TaskCreated", TaskID: "done", Surface: string(authz.System), Payload: []byte(`{"source":"qa","external_id":"done","project":"p"}`)}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, err := s.Lease("done", "local-claude", time.Minute); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
transcript := filepath.Join(t.TempDir(), "transcript.jsonl")
|
||||
if err := os.WriteFile(transcript, []byte(`{"message":{"usage":{"input_tokens":100,"cache_read_input_tokens":20,"cache_creation_input_tokens":5,"output_tokens":7}}}`+"\n"), 0600); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
task, _ := s.Task("done")
|
||||
body, _ := json.Marshal(map[string]string{"task_id": "done", "worker_id": "local-claude", "lease_epoch": task.Lease.Epoch, "transcript_path": transcript, "report": "# done"})
|
||||
req := httptest.NewRequest(http.MethodPost, "/v1/harness/complete", bytes.NewReader(body))
|
||||
res := httptest.NewRecorder()
|
||||
harnessCompletion{store: s, token: "secret"}.ServeHTTP(res, req)
|
||||
if res.Code != http.StatusUnauthorized {
|
||||
t.Fatalf("missing token status = %d, want 401", res.Code)
|
||||
}
|
||||
req.Header.Set("Authorization", "Bearer secret")
|
||||
req = httptest.NewRequest(http.MethodPost, "/v1/harness/complete", bytes.NewReader(body))
|
||||
req.Header.Set("Authorization", "Bearer secret")
|
||||
res = httptest.NewRecorder()
|
||||
harnessCompletion{store: s, token: "secret"}.ServeHTTP(res, req)
|
||||
if res.Code != http.StatusOK {
|
||||
t.Fatalf("completion status = %d: %s", res.Code, res.Body.String())
|
||||
}
|
||||
task, ok := s.Task("done")
|
||||
if !ok || task.State != domain.StateCompleted {
|
||||
t.Fatalf("task after completion = %#v, present=%v", task, ok)
|
||||
}
|
||||
var completed struct {
|
||||
Receipt struct {
|
||||
Input int `json:"input_tokens"`
|
||||
CacheRead int `json:"cache_read_tokens"`
|
||||
CacheWrite int `json:"cache_write_tokens"`
|
||||
Output int `json:"output_tokens"`
|
||||
} `json:"receipt"`
|
||||
}
|
||||
for _, e := range s.Events(0) {
|
||||
if e.Type == "TaskCompleted" {
|
||||
if err := json.Unmarshal(e.Payload, &completed); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
if completed.Receipt.Input != 100 || completed.Receipt.CacheRead != 20 || completed.Receipt.CacheWrite != 5 || completed.Receipt.Output != 7 {
|
||||
t.Fatalf("receipt = %#v", completed.Receipt)
|
||||
}
|
||||
var quota struct {
|
||||
Harness string `json:"harness_id"`
|
||||
Consumed float64 `json:"consumed"`
|
||||
}
|
||||
found := false
|
||||
for _, e := range s.Events(0) {
|
||||
if e.Type == "QuotaReported" {
|
||||
_ = json.Unmarshal(e.Payload, "a)
|
||||
found = true
|
||||
}
|
||||
}
|
||||
if !found || quota.Harness != "local-claude" || quota.Consumed != 125 {
|
||||
t.Fatalf("quota report = %#v, found=%v", quota, found)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMultiMachineRegistryRequiresKnownLocalMachine(t *testing.T) {
|
||||
path := filepath.Join(t.TempDir(), "config.json")
|
||||
if err := os.WriteFile(path, []byte(`{
|
||||
|
||||
Reference in New Issue
Block a user