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
This commit is contained in:
kami
2026-07-27 22:25:53 +04:00
parent 3fe3aee5b7
commit 0ca78243b9
7 changed files with 225 additions and 8 deletions
+16
View File
@@ -135,6 +135,22 @@ type HandoffRequester interface {
func (a CLIAdapter) RequestHandoff(ctx context.Context, s Session) error {
return a.Client.Prompt(ctx, s.PaneID, handoffPrompt, time.Minute)
}
// conventionsPrompt is §6.3's "orchestra injects a notice to agents whose
// current task is adjacent" — staleness is tracked here, not by trusting the
// agent's cached view of the shared docs.
const conventionsPrompt = `Notice from Orchestra: the shared project conventions (AGENTS.md / CLAUDE.md / VOCAB.md) have been updated since you started this task. Re-read them now before continuing, in case something you're relying on has changed.`
// ConventionsNotifier is the optional capability rotate()'s convention-drift
// check uses; adapters without a live pane (tests, non-interactive harnesses)
// can omit it.
type ConventionsNotifier interface {
NotifyConventionsChanged(context.Context, Session) error
}
func (a CLIAdapter) NotifyConventionsChanged(ctx context.Context, s Session) error {
return a.Client.Prompt(ctx, s.PaneID, conventionsPrompt, time.Minute)
}
// Release reads the §6.1 handoff the agent wrote to HandoffFile at the
// worktree root, validates its schema and anchor against the worktree's real
// HEAD, uploads it to CAS, and only then releases herdr's claim on the pane
+6
View File
@@ -157,6 +157,12 @@ type Session struct {
// its §6.1 handoff (HandoffFile) — avoids re-sending the same prompt
// every tick while Release keeps waiting for the file to appear.
HandoffRequested bool `json:"handoff_requested,omitempty"`
// ConventionsHash is continuity.ConventionsHash of the project's shared
// *.md docs (AGENTS.md/CLAUDE.md/VOCAB.md) at the time this session was
// last notified of (or started with) their content — §6.3's staleness
// tracking lives at the orchestra layer, never trusted from the agent's
// cached view.
ConventionsHash string `json:"conventions_hash,omitempty"`
}
func (c *Client) Prompt(ctx context.Context, pane, text string, wait time.Duration) error {