mirror of
https://github.com/stablyai/orca.git
synced 2026-10-25 08:04:05 +00:00
docs(orchestration): clarify coordinator authority for agents
This commit is contained in:
File diff suppressed because one or more lines are too long
@@ -0,0 +1,20 @@
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import { ORCHESTRATION_COMMAND_SPECS } from './orchestration'
|
||||
|
||||
describe('orchestration command specs', () => {
|
||||
it('describes run-use as a fenced authority claim for agents', () => {
|
||||
const runUse = ORCHESTRATION_COMMAND_SPECS.find(
|
||||
(spec) => spec.path.join(' ') === 'orchestration run-use'
|
||||
)
|
||||
const guidance = [runUse?.summary, ...(runUse?.notes ?? [])].join('\n')
|
||||
|
||||
expect(guidance).toContain('coordinator authority')
|
||||
expect(guidance).toContain('owning host proves the prior coordinator exited')
|
||||
expect(guidance).toContain('live')
|
||||
expect(guidance).toContain('unverifiable')
|
||||
expect(guidance).toContain('consumer_fenced')
|
||||
expect(guidance).toContain('Do not retry blindly')
|
||||
expect(guidance).toContain('--takeover-legacy')
|
||||
expect(guidance).toContain('not a force override for ordinary Runs')
|
||||
})
|
||||
})
|
||||
@@ -16,12 +16,14 @@ export const ORCHESTRATION_COMMAND_SPECS: CommandSpec[] = [
|
||||
},
|
||||
{
|
||||
path: ['orchestration', 'run-use'],
|
||||
summary: 'Bind this coordinator terminal to an existing Run',
|
||||
summary: 'Claim coordinator authority for an existing Run',
|
||||
usage:
|
||||
'orca orchestration run-use --id <run_id> [--from <handle>] [--takeover-legacy] [--retry-request <id>] [--json]',
|
||||
allowedFlags: [...GLOBAL_FLAGS, 'id', 'from', 'takeover-legacy', 'retry-request'],
|
||||
notes: [
|
||||
'--takeover-legacy must run in the live coordinator agent terminal it binds; it preserves existing worker assignments.'
|
||||
'Rebinding the same live coordinator preserves authority and Delivery. A different coordinator succeeds only when the owning host proves the prior coordinator exited.',
|
||||
'A live or unverifiable owner returns consumer_fenced with structured recovery steps. Do not retry blindly or treat loss of contact as exit.',
|
||||
'--takeover-legacy is only for the automatically adopted legacy Run; it is not a force override for ordinary Runs.'
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
@@ -153,12 +153,28 @@ export function bindRun(
|
||||
(!observationMatches || observation.status !== 'exited')
|
||||
) {
|
||||
const coordinatorStatus = observationMatches ? observation.status : 'unverifiable'
|
||||
const inspectCommand = `orca orchestration run-show --id ${params.runId} --json`
|
||||
const retryCommand = `orca orchestration run-use --id ${params.runId} --json`
|
||||
const nextSteps =
|
||||
coordinatorStatus === 'live'
|
||||
? [
|
||||
'Continue from the owning coordinator terminal; this caller has read-only inspection authority.',
|
||||
`To intentionally transfer authority, stop or exit that coordinator process, then run ${retryCommand} from the replacement.`,
|
||||
`Inspect current authority with ${inspectCommand}; binding.currentConsumer is true only for the owner.`,
|
||||
'Do not retry while coordinatorStatus is live. No force-steal exists for an ordinary Run.'
|
||||
]
|
||||
: [
|
||||
'Restore connectivity to the owning host. Loss of contact is not evidence of exit.',
|
||||
`Inspect current authority with ${inspectCommand}; binding.currentConsumer is true only for the owner.`,
|
||||
`Run ${retryCommand} only after the owning host proves the incumbent exited.`,
|
||||
'If the incumbent is live, continue from its coordinator terminal; no force-steal exists for an ordinary Run.'
|
||||
]
|
||||
throw new OrchestrationError(
|
||||
'consumer_fenced',
|
||||
coordinatorStatus === 'live'
|
||||
? 'This Run is owned by another live coordinator. No effects were applied.'
|
||||
: 'This Run coordinator could not be proven exited. Retry from the owning coordinator terminal after connectivity is restored. No effects were applied.',
|
||||
{ effectsApplied: false, coordinatorStatus }
|
||||
{ effectsApplied: false, coordinatorStatus, nextSteps }
|
||||
)
|
||||
}
|
||||
this.unbindOtherRunsForPane(params.coordinatorPaneKey, params.runId)
|
||||
|
||||
@@ -128,7 +128,16 @@ describe('orchestration RPC methods', () => {
|
||||
})
|
||||
).rejects.toMatchObject({
|
||||
code: 'consumer_fenced',
|
||||
data: { effectsApplied: false, coordinatorStatus: 'live' }
|
||||
data: {
|
||||
effectsApplied: false,
|
||||
coordinatorStatus: 'live',
|
||||
nextSteps: [
|
||||
expect.stringContaining('owning coordinator terminal'),
|
||||
expect.stringContaining('stop or exit that coordinator process'),
|
||||
expect.stringContaining(`run-show --id ${created.run.id} --json`),
|
||||
expect.stringContaining('No force-steal exists for an ordinary Run')
|
||||
]
|
||||
}
|
||||
})
|
||||
const inspected = (await call('orchestration.taskList', {
|
||||
run: created.run.id,
|
||||
@@ -186,7 +195,16 @@ describe('orchestration RPC methods', () => {
|
||||
call('orchestration.runUse', { id: run.id, from: 'term_new' })
|
||||
).rejects.toMatchObject({
|
||||
code: 'consumer_fenced',
|
||||
data: { effectsApplied: false, coordinatorStatus: 'unverifiable' }
|
||||
data: {
|
||||
effectsApplied: false,
|
||||
coordinatorStatus: 'unverifiable',
|
||||
nextSteps: expect.arrayContaining([
|
||||
expect.stringContaining('Restore connectivity to the owning host'),
|
||||
expect.stringContaining('Loss of contact is not evidence of exit'),
|
||||
expect.stringContaining(`run-show --id ${run.id} --json`),
|
||||
expect.stringContaining('only after the owning host proves the incumbent exited')
|
||||
])
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
Reference in New Issue
Block a user