Commit Graph

47 Commits

Author SHA1 Message Date
kami 6fd7738a02 fix(herdr): rewrite CodexActivity against the real live rollout shape (S11)
The previous function_call/function_call_output shape was never verified
and doesn't exist in any real Codex rollout. Confirmed the real shape
against this machine's own ~/.codex/sessions files: file edits arrive as
event_msg/patch_apply_end (changes+success, no pairing needed), and shell
commands arrive as a freeform custom_tool_call named "exec" whose input is
a JS snippet embedding cmd:"..." rather than a flat arguments object, with
failure signaled by a literal "Script error:" prefix in the output text.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W1rkJ2hBMybnJctPbcy4tT
2026-07-28 00:19:48 +04:00
kami c85fb81663 feat(orchestrator): milestone rotation and thrash detection (S11)
Closes the last two S11 triggers. internal/herdr/activity.go normalizes
tool/function calls per harness (ClaudeActivity verified against the
existing transcript format, CodexActivity best-effort/unverified,
OpenCodeActivity refuses — no confirmed per-tool-call source exists) and
implements the three thrash rules plus a narrow milestone check
(successful git commit as the last call).

CLIAdapter.RequestHandoffReason asks the agent to write a handoff with
meta.reason set, same "ask, don't invent" pattern as the existing handoff/
report requests. rotate() and TurnDecision generalize the manual-bypass
shortcut to manual/milestone/thrash and request (never directly release)
on a detected trigger.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W1rkJ2hBMybnJctPbcy4tT
2026-07-28 00:09:57 +04:00
kami e363a77ae9 feat(store): add TaskCorrected compensating-event type (S8)
Implements §3.1's invariant that a wrong event is never edited, only
compensated for by a new appended event. TaskCorrected references the
event it repairs and can change state and/or amend-style fields;
Store.Append verifies the referenced event actually exists on the task.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W1rkJ2hBMybnJctPbcy4tT
2026-07-27 23:48:19 +04:00
kami 86cc0b9276 feat(orchestrator): agent-initiated ROTATE via handoff reason=manual (S11)
rotate() and TurnDecision now check the agent's own handoff for
meta.reason=="manual" before evaluating occupancy/turn-boundary — per
spec §5.3, that reason is itself the boundary signal ("a coherent unit
finished and the next is independent"), so it bypasses both checks and
releases immediately. Extracted the shared release-and-anchor-certify
tail into Coordinator.finishRelease so the manual path gets the same
anchor safety guarantee as the threshold path.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W1rkJ2hBMybnJctPbcy4tT
2026-07-27 23:44:04 +04:00
kami 84d09ce114 feat(orchestrator): soft occupancy threshold requests handoff early (S11 partial)
Coordinator.Soft (default 0.55, ORCHESTRA_OCCUPANCY_SOFT) makes rotate()
and TurnDecision request a handoff advisory-only once occupancy crosses
the soft threshold, well before Hard forces a release/rotation.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W1rkJ2hBMybnJctPbcy4tT
2026-07-27 23:40:46 +04:00
kami 8b4955a687 feat(federation): admission control on worker registration (S10)
Register() previously trusted a self-declared id and self-chosen token
from any caller, and let a second caller silently hijack an existing
worker id by re-registering it with a different token. Adds an optional
pre-shared AdmitToken (ORCHESTRA_FEDERATION_ADMIT_TOKEN) and requires a
same-id re-registration to present the existing worker's own token.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W1rkJ2hBMybnJctPbcy4tT
2026-07-27 23:34:02 +04:00
kami 72f6230b4a 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
2026-07-27 23:31:10 +04:00
kami 44376f0709 fix(store): TaskAmended applies description/priority/due, not just title (S7)
Amendments to due/description/inherent_priority were accepted and durably
logged but silently discarded by the projection since store.apply only
ever handled the title key. Also added the missing Task.Description field
(TaskCreated never populated it either).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W1rkJ2hBMybnJctPbcy4tT
2026-07-27 23:26:24 +04:00
kami 5fb88724bd fix(operations): per-project git sync + completion receipts in brief (S2, S3)
Brief.Git was a single GitSync read from ORCHESTRA_DATA (never a git
checkout), and completions were counted but discarded their report_ref/
receipt. Brief.Git is now keyed by project ID and built from each
project's real repo; GitSync gained Ahead/Behind vs upstream; Brief now
carries Receipts pulled from each TaskCompleted payload.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W1rkJ2hBMybnJctPbcy4tT
2026-07-27 23:25:01 +04:00
kami 1f46a34afb fix(delivery): stop killing the fanout goroutine on a single send error
Closes S4 (AUDIT.md): Fanout.Run returned on the first sender error,
permanently ending notifications for the process lifetime after one ntfy
hiccup. Failed sends now go through an OnError hook and the loop
continues. Also persists the delivery cursor to a file next to
ORCHESTRA_DATA so a restart resumes from the last delivered event instead
of re-notifying the entire log from seq 0. Adds the package's first test.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W1rkJ2hBMybnJctPbcy4tT
2026-07-27 23:19:15 +04:00
kami 0ca78243b9 feat(continuity): wire §6.3 shared-docs staleness notice
MarkdownChanges was deleted as dead code, but the underlying spec
requirement wasn't abandoned — rebuilt it independently. Adds
continuity.ConventionsHash for AGENTS.md/CLAUDE.md/VOCAB.md, tracks a
per-session snapshot on herdr.Session, and adds
Coordinator.checkConventions (run every Monitor tick) which compares
each active session's snapshot against its project's base repo and
pushes an in-pane notice via a new herdr.ConventionsNotifier
capability when they drift.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W1rkJ2hBMybnJctPbcy4tT
2026-07-27 22:25:53 +04:00
kami 3fe3aee5b7 fix(herdr): close Phase 4 item 2 — actually ask the agent for a handoff
Release already validated and uploaded a §6.1 handoff, but nothing ever
told the agent the .orchestra-handoff.json convention existed, so the
file it waited on never got written. rotate() now prompts the agent
once via a new optional herdr.HandoffRequester capability
(CLIAdapter.RequestHandoff) when the file is missing, and defers
Release until it appears, mirroring the .orchestra-report.md/B3 ask
pattern rather than inventing a handoff.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W1rkJ2hBMybnJctPbcy4tT
2026-07-27 22:10:22 +04:00
kami 62bb17e05d fix(continuity): wire scratch-commit-before-release and rewrite bootstrap prompt (Phase 4 items 3, 5, 6)
Release now re-verifies every handoff Anchor.Dirty file hash (previously
unchecked after the top-level anchor SHA compare), snapshots dirty state
onto a per-task scratch branch before uploading, and rewrites the anchor
to the new commit so successor pickup collapses to a single HEAD compare.
ScratchCommit made idempotent for repeated rotations of the same task.

Bootstrap's prompt now points the agent at the scratch-branch commit
history instead of vague "read the handoff" prose, and does not claim a
GET /v1/artifacts/<ref> endpoint that doesn't exist.

MarkdownChanges had zero callers and zero tests; deleted per AUDIT.md's
explicit deletion option rather than half-wiring an undesigned feature.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W1rkJ2hBMybnJctPbcy4tT
2026-07-27 22:06:06 +04:00
kami 7bcad64398 fix(orchestrator): wire TASK.md writing and §6.2 pickup validation (B6, partial)
Fixes AUDIT.md's B6: nothing wrote a TASK.md into a worktree, so
continuity.ValidatePickup had no caller and no file to check.

- continuity.RenderTaskFile/TaskFileHash: render and hash the immutable
  §6.2 TASK.md from a domain.Task.
- GitWorktrees.Create writes and commits TASK.md into every freshly
  created worktree (must be committed, not dirty, for ScratchCommit's
  immutability check and for a stable hash).
- Coordinator.Start now runs continuity.ValidatePickup (anchor SHA,
  dirty-file hashes, TASK.md hash) against the real worktree before
  bootstrapping a successor onto a handoff_ref, and blocks the task
  instead of bootstrapping on a validation failure.

Still open from Phase 4: handoff production (agent writing the real
handoff; Release still refuses per B5), ScratchCommit wiring before
release, and the §6.2 bootstrap-prompt rewrite — see AUDIT.md.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W1rkJ2hBMybnJctPbcy4tT
2026-07-27 21:44:00 +04:00
kami f8a397a14c fix(harness): add automatic TaskCompleted producer (B3, partial)
POST /v1/harness/complete lets a Claude Code Stop hook report task
completion instead of relying on a human hitting the manual endpoint.
The hook only fires on an explicit .orchestra-report.md marker (not
every turn boundary); the server builds the receipt itself from the
real transcript via herdr.ClaudeUsage rather than trusting a
self-reported number. Codex/opencode producers and the turn-decision
endpoint are still unbuilt — see AUDIT.md/progress.md for scope.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W1rkJ2hBMybnJctPbcy4tT
2026-07-27 21:24:17 +04:00
kami 63cda5557e fix(herdr): B5 — replace invented pane.kill/release/rotation_signal with real methods
Verified against a live herdr instance (192.168.1.105:9245) that pane.kill,
pane.release, and pane.rotation_signal never existed in the protocol, as
AUDIT.md's B5 suspected. Real method list captured in deploy/herdr-schema.json.

- Kill now calls the real pane.close({pane_id}).
- RotationSignal interface/method/call-site deleted; no real equivalent exists.
- Release now refuses loudly instead of calling a nonexistent method — the
  real pane.release_agent can't return a handoff_ref either way (herdr
  doesn't write handoffs, the agent does), so a real fix needs Phase 4
  handoff production first.

Also documents Phase 0 findings in AUDIT.md/progress.md, and adds
CLAUDE.md/AGENTS.md with project-specific knowledge (herdr protocol facts,
deployment topology, a currently-stuck live task, the federation fork) for
future sessions.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W1rkJ2hBMybnJctPbcy4tT
2026-07-27 21:05:53 +04:00
kami 02d93fb63d docs: track AUDIT.md remediation progress
Record what's landed this pass (B1, B2, B4, B8, S1, S5, S6) and what's
still open, so the next session doesn't have to re-derive it from git log.
2026-07-27 19:44:42 +04:00
kami ce6f02f9e6 checkpoint: multi-repo Gitea ingestion, per-project repos, rotation anchor_sha fix
Pre-existing uncommitted work found at session start: rotation now emits
anchor_sha on TaskReleased (previously silently dropped by store.Append
validation), multi-repo Gitea provider support, per-project git worktree
roots, and associated test coverage. Committing as a checkpoint before
starting remediation work tracked in AUDIT.md.
2026-07-27 18:15:02 +04:00
kami 98833ffb1a record completion of remaining orchestration gaps 2026-07-26 20:39:57 +04:00
kami 4364dff9c2 support milestone and thrash rotation signals 2026-07-26 20:36:17 +04:00
kami b4d9621d89 schedule daily standup advisories 2026-07-26 20:35:57 +04:00
kami 17e7aef871 wire configured quota limits into routing 2026-07-26 20:34:38 +04:00
kami 6e4df6d2ff add federated worker registration and heartbeats 2026-07-26 20:32:45 +04:00
kami 26011ed33c coordinate rotation at harness turn boundaries 2026-07-26 20:32:01 +04:00
kami 4093bdb683 add telegram and ntfy event delivery 2026-07-26 20:31:42 +04:00
kami f818003ad5 add conservative quota availability filtering 2026-07-26 20:31:03 +04:00
kami ae4d3a57bc supervise providers and reflect terminal state 2026-07-26 20:30:19 +04:00
kami ad32f29cd5 persist and reconcile runtime sessions 2026-07-26 20:28:41 +04:00
kami afac166989 add bounded artifact upload endpoint 2026-07-26 20:25:40 +04:00
kami 98725c28c5 validate and select configured harness adapters 2026-07-26 20:25:17 +04:00
kami 4e05e4df7b harden versioned event substrate 2026-07-26 20:19:18 +04:00
kami 6bf6445d40 enforce lifecycle evidence contracts 2026-07-26 20:17:03 +04:00
kami b2b24cbe09 docs: add canonical full implementation gap list 2026-07-26 20:13:36 +04:00
kami 5a360c051c feat: rotate sessions on occupancy threshold 2026-07-26 20:07:34 +04:00
kami dc3cebebf8 feat: wire configured harness execution 2026-07-26 20:06:44 +04:00
kami 5d45351613 feat: enforce event authorization and readiness 2026-07-26 19:52:49 +04:00
kami 64abbe900e feat: start provider ingestion and orchestration coordination 2026-07-26 19:49:41 +04:00
kami aa6719ca16 docs: update server implementation gaps 2026-07-26 19:47:08 +04:00
kami 073d5c69b0 docs: record implementation review gaps 2026-07-26 19:42:54 +04:00
kami 8822e028bb Implement projections and operations 2026-07-26 19:14:46 +04:00
kami 9937cd5cd0 Implement authorization and control surfaces 2026-07-26 19:13:09 +04:00
kami 1c889167fa Implement continuity handoffs and pickup validation 2026-07-26 19:10:18 +04:00
kami 96e94bc2d0 Implement herdr integration layer 2026-07-26 19:07:03 +04:00
kami a3b9f63892 Implement router assignment and lease retries 2026-07-26 19:04:32 +04:00
kami 7980839393 implement project and machine registries 2026-07-26 19:01:44 +04:00
kami 0a21e1bc2b Implement provider layer adapters 2026-07-26 18:59:13 +04:00
kami 24ee81d538 complete item 1 task substrate 2026-07-26 18:57:09 +04:00