v3 workflow: intent, phases, review, submission, enforcement, burn-in

The v3 stack, previously an uncommitted working tree, plus this session's two
units and the burn-in instrument. This commit is the burn-in build identity:
coordinator and worker must both report this revision before a task is created.

Workflow (earlier sessions, uncommitted until now): human decision events and
reduction, source cursors and reconcile-before-launch, turn-boundary
reconciliation, internal/agentctx as the single renderer, ace-fca phases with
sealed artifacts, the trajectory gate, bounded grilling, independent review,
task pr enforcement, and human review reflection.

Capability restrictions at the agent boundary: an authz.Agent surface at
GatedWrite may ask and may not act. It also fixes two bugs the unit exposed --
gated surfaces could not reach the two endpoints written for them, and
RequestHumanDecision would block an unowned task while rejecting a question
from the session that did own it.

Turn-boundary reconcile-failure escalation: a streak of consecutive failures
asks the session to hand off, fenced on the lease epoch, with reconcile_failure
as a real handoff reason. The worker was dropping the coordinator's verdict on
the floor; it now acts on it.

Burn-in: herdr.WriteLaunchContext dumps the exact agentctx.Build result to
<worktree>/.orchestra/launch.md at every launch, local and federated. BURNIN.md
is the runbook. deploy/build.sh stamps both binaries from one commit.

go build, go vet and go test ./... pass, 20 packages.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-26 18:31:20 +04:00
parent 97a9c65302
commit 7f12c7fc37
78 changed files with 16417 additions and 352 deletions
+65
View File
@@ -17,9 +17,40 @@ ORCHESTRA_PORT=9145
# ORCHESTRA_FEDERATION_ADMIT_TOKEN=<homesrv-admission-secret>
# ORCHESTRA_WORKER_HERDR_ID=workpc-opencode
# ORCHESTRA_WORKER_HARNESS=opencode
# Pane/process backend. Defaults to herdr. tmux is currently supported only
# for Claude Code workers; Codex and OpenCode should remain on herdr.
# ORCHESTRA_WORKER_BACKEND=herdr
# ORCHESTRA_WORKER_HERDR=/home/orchestra/.config/herdr/herdr.sock
# With ORCHESTRA_WORKER_BACKEND=tmux, ORCHESTRA_WORKER_HERDR is not used.
# A bare value selects an isolated tmux -L socket; an absolute path selects -S.
# ORCHESTRA_WORKER_TMUX_SOCKET=orchestra
# Optional Claude executable override; defaults to resolving `claude` in PATH.
# ORCHESTRA_WORKER_HARNESS_COMMAND=/home/orchestra/.local/bin/claude
# ORCHESTRA_WORKER_STATE=/var/lib/orchestra-worker/state.json
# ORCHESTRA_GIT_REMOTE=origin
#
# One worker process can serve several harnesses (several multiplexers and
# several agents) by declaring them in a JSON file. The variables above then
# describe nothing: each entry carries its own backend and harness. Every
# declared harness is a separate federation identity, because the coordinator
# authorizes lease calls by comparing the worker id against the lease's harness
# id, so each needs its own token and registers separately.
# ORCHESTRA_WORKER_HARNESS_CONFIG_FILE=/etc/orchestra/harnesses.json
# [
# {"id":"workpc-claude","harness":"claude","backend":"tmux",
# "tmux_socket":"orchestra","command":"/home/kami/.local/bin/claude"},
# {"id":"workpc-opencode","harness":"opencode","backend":"herdr",
# "herdr":"127.0.0.1:9247"}
# ]
# Tokens belong in the environment rather than that file. Each id maps to
# ORCHESTRA_WORKER_TOKEN_<ID>, uppercased with every other character underscored:
# ORCHESTRA_WORKER_TOKEN_WORKPC_CLAUDE=<per-identity-secret>
# ORCHESTRA_WORKER_TOKEN_WORKPC_OPENCODE=<per-identity-secret>
# Each identity keeps its own state file. Set the directory holding them, or a
# per-entry "state" path; the default derives one per id next to the worktrees.
# ORCHESTRA_WORKER_STATE_DIR=/var/lib/orchestra-worker
# ORCHESTRA_WORKER_ID still names the process for the single-harness form, where
# it must equal ORCHESTRA_WORKER_HERDR_ID.
ORCHESTRA_MACHINE_ID=homesrv # required when the registry has multiple machines
# Static project/machine/herdr topology (registry.Load). Required for
@@ -70,6 +101,30 @@ ORCHESTRA_CONTEXT_WINDOW=200000
#ORCHESTRA_GITEA_REPO=
#ORCHESTRA_GITEA_WEBHOOK_SECRET=
# Human-input reconciliation. When a Gitea source is configured, issue
# comments are imported as human decisions immediately before every lease,
# and a source that cannot be read refuses the lease instead of letting a
# successor resume from an older intent. Set to "off" only to keep leasing
# while a source is known down; agents then run without newer comments.
#ORCHESTRA_HUMAN_RECONCILE=off
# How many consecutive failed turn-boundary reconciles ask the running session
# to hand off. Default 3. The successor's pre-lease reconcile then fails closed
# while the source is still down, so the task waits instead of running on
# intent Orchestra cannot refresh.
#ORCHESTRA_RECONCILE_FAILURE_HANDOFF=3
# Base branch for pull requests created by `task pr`. Defaults to master. The
# pull request is created or updated for the task branch orchestra/<task-id>,
# never duplicated: a repeated submission refreshes the same review.
#ORCHESTRA_PR_BASE=master
# Whose words on a submitted pull request may reopen a task. ACTORS is an
# allow-list of forge logins; empty trusts anyone not ignored, which is only
# safe on a private forge with no bots. IGNORE_ACTORS always loses. Comments at
# or before the submission never reopen anything.
#ORCHESTRA_REVIEW_ACTORS=kami
#ORCHESTRA_REVIEW_IGNORE_ACTORS=gitea-actions,orchestra-bot
# --- Delivery (notify-only surfaces) ---
# Telegram: both required together.
#ORCHESTRA_TELEGRAM_BOT_TOKEN=
@@ -95,6 +150,16 @@ ORCHESTRA_WEB_PASSWORD_HASH=
#ORCHESTRA_UI_INSECURE_COOKIE=1
#ORCHESTRA_MCP_TOKEN=
#ORCHESTRA_MAVEN_TOKEN=
# The credential an in-pane coding session may hold. It buys read access plus
# the three request endpoints (approval, decision-request, deferred) and
# nothing else: phase, review, submission, completion and lease changes are
# refused for this surface at the endpoint and again at the bus. This is the
# ONLY Orchestra credential that may enter an agent pane; the forge, Vikunja,
# worker and operator tokens must stay in the worker.
#ORCHESTRA_AGENT_TOKEN=
# The turn-boundary endpoint's own token (/v1/harness/turn), authenticated in
# the handler rather than by the surface gate.
#ORCHESTRA_HARNESS_TOKEN=
# Inbound bearer tokens for the notify-only surfaces, separate from the
# credentials used to *send* (ORCHESTRA_TELEGRAM_BOT_TOKEN, ORCHESTRA_NTFY_TOKEN).
# S12: ORCHESTRA_NTFY_TOKEN used to serve both roles, so configuring ntfy