Let the validator accept the reason the adapter produces
handoffReason has emitted "phase_changed" since phase rotations landed. The continuity validator's reason list was never extended, so every phase rotation built a handoff it then refused as "invalid handoff meta". Live on run 5: with F31 clearing the parse ahead of it, the release reached this and stopped at phase "prepared" with "adapter: upload handoff: invalid handoff meta". The test asserts the property rather than the constant: every reason the adapter can produce must survive Validate, including its fallback. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011xsXyr5J1RACo71YeKG3Pu
This commit is contained in:
@@ -132,7 +132,12 @@ type Result struct {
|
||||
// reconcile_failure is Orchestra's own trigger: human input could not be
|
||||
// reconciled at repeated verified turn boundaries, so the session is handed to
|
||||
// a successor rather than left running on intent that cannot be refreshed.
|
||||
var reasons = map[string]bool{"threshold": true, "milestone": true, "thrash": true, "manual": true, "reconcile_failure": true}
|
||||
// phase_changed is a rotation Orchestra itself triggers when a phase request
|
||||
// is accepted. The adapter has produced it since phase rotations landed
|
||||
// (handoffReason), but this list was never extended, so every phase rotation
|
||||
// built a handoff the validator then refused as "invalid handoff meta" (F36).
|
||||
// The two halves of one contract have to name the same vocabulary.
|
||||
var reasons = map[string]bool{"threshold": true, "milestone": true, "thrash": true, "manual": true, "reconcile_failure": true, "phase_changed": true}
|
||||
|
||||
const maxAuthoredLine = 200
|
||||
|
||||
|
||||
@@ -315,3 +315,22 @@ func TestReleaseRequiresCAS(t *testing.T) {
|
||||
t.Fatal("expected error when CAS is nil")
|
||||
}
|
||||
}
|
||||
|
||||
// TestEveryReasonTheAdapterProducesIsAcceptedByTheValidator guards F36. The
|
||||
// adapter gained "phase_changed" when phase rotations landed and the
|
||||
// validator's vocabulary did not, so every phase rotation built a handoff that
|
||||
// was then refused as "invalid handoff meta". A live run reached exactly this
|
||||
// point after F31 unblocked the parse ahead of it.
|
||||
func TestEveryReasonTheAdapterProducesIsAcceptedByTheValidator(t *testing.T) {
|
||||
for _, reason := range []string{"threshold", "milestone", "thrash", "manual", "reconcile_failure", "phase_changed", "something the adapter does not know"} {
|
||||
produced := handoffReason(Session{HandoffReason: reason})
|
||||
h := continuity.Handoff{
|
||||
Meta: continuity.Meta{ID: "agent-1", Reason: produced},
|
||||
Anchor: continuity.Anchor{GitSHA: "0000000000000000000000000000000000000000", Branch: "main"},
|
||||
Action: "write the research note",
|
||||
}
|
||||
if err := h.Validate(); err != nil {
|
||||
t.Fatalf("adapter produces reason %q for %q, validator refuses it: %v", produced, reason, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user