mirror of
https://github.com/stablyai/orca.git
synced 2026-09-25 00:02:35 +00:00
fix(agent-hooks): move advertised-capability source onto the ingest envelope
ingestRemote() gained a third positional argument in this PR (advertisedAgentStatusCapabilities) to satisfy a new ratchet requiring every legacy-ingress call site to name its capability source. Both production callers pass the same constant every time, so the argument carries zero runtime information — but Vitest's toHaveBeenCalledWith matches argument count exactly, so the pre-existing SSH relay integration test (which asserts a 2-argument call) started failing even though nothing about the actual admission decision changed. Capabilities are a property of the producing peer/connection, not an orthogonal call parameter, so move the field onto the envelope object instead of adding a third positional argument: ingestRemote reads envelope.advertisedAgentStatusCapabilities (defaulting to the unadvertised-legacy-peer set), and both call sites stamp the constant onto their envelope literal. Call arity stays at two arguments, so the pre-existing evidence test needs no change. The envelope never crosses the wire in either caller: SSH rebuilds it field-by-field from the RPC params, and the WSL path copies (never mutates) the wire-deserialized notification before stamping the field on, so this is purely an internal main-process shape change. Also strengthens the ingress ratchet test that required this: it previously only checked that the capability constant's name appeared somewhere in each caller's source, which a stray unused import could satisfy. It now asserts the actual `advertisedAgentStatusCapabilities: AGENT_STATUS_LEGACY_UNADVERTISED_PEER_CAPABILITIES` key:value binding is present.
This commit is contained in:
@@ -653,10 +653,10 @@ describe('AgentHookServer ingestRemote', () => {
|
||||
paneKey: PANE,
|
||||
tabId: 'tab-1',
|
||||
worktreeId: 'wt-1',
|
||||
advertisedAgentStatusCapabilities: [],
|
||||
payload: { state: 'working', prompt: 'unsupported peer', agentType: 'claude' }
|
||||
},
|
||||
'conn-1',
|
||||
[]
|
||||
'conn-1'
|
||||
)
|
||||
const olderPeerRow = server.getStatusSnapshot()[0]
|
||||
|
||||
@@ -665,10 +665,10 @@ describe('AgentHookServer ingestRemote', () => {
|
||||
paneKey: PANE,
|
||||
tabId: 'tab-1',
|
||||
worktreeId: 'wt-1',
|
||||
advertisedAgentStatusCapabilities: [AGENT_STATUS_RUNS_RUNTIME_CAPABILITY],
|
||||
payload: { state: 'done', prompt: 'capable peer', agentType: 'claude' }
|
||||
},
|
||||
'conn-1',
|
||||
[AGENT_STATUS_RUNS_RUNTIME_CAPABILITY]
|
||||
'conn-1'
|
||||
)
|
||||
|
||||
expect(server.getStatusSnapshot()).toEqual([olderPeerRow])
|
||||
|
||||
@@ -52,15 +52,19 @@ export abstract class AgentHookServerIngestRemote extends AgentHookServerIngestS
|
||||
/** Payload fields the relay dropped to fit an oversized frame; validated below. */
|
||||
shedFields?: unknown
|
||||
claudeRunningNonAgentTask?: unknown
|
||||
/** The producing peer's advertised run-capability set — a property of the peer/connection that built this envelope, not an orthogonal call parameter. Absent (older relay/HTTP paths) defaults to the unadvertised-legacy-peer set. */
|
||||
advertisedAgentStatusCapabilities?: readonly string[]
|
||||
payload: unknown
|
||||
},
|
||||
connectionId: string | null,
|
||||
advertisedAgentStatusCapabilities: readonly string[] = AGENT_STATUS_LEGACY_UNADVERTISED_PEER_CAPABILITIES
|
||||
connectionId: string | null
|
||||
): void {
|
||||
if (
|
||||
!canAdmitLegacyAgentStatus(
|
||||
'main-status-update',
|
||||
olderPeerAgentStatusLegacyMode(advertisedAgentStatusCapabilities)
|
||||
olderPeerAgentStatusLegacyMode(
|
||||
envelope?.advertisedAgentStatusCapabilities ??
|
||||
AGENT_STATUS_LEGACY_UNADVERTISED_PEER_CAPABILITIES
|
||||
)
|
||||
)
|
||||
) {
|
||||
return
|
||||
|
||||
@@ -100,12 +100,17 @@ export const defaultWslHookRelayDeps: WslHookRelayManagerDeps = {
|
||||
spawnRelay: spawnWslRelayProcess,
|
||||
runInstall: runWslInstallProcess,
|
||||
waitForSentinel: waitForWslRelaySentinel,
|
||||
ingest: (envelope, connectionId) =>
|
||||
agentHookServer.ingestRemote(
|
||||
envelope as Parameters<typeof agentHookServer.ingestRemote>[0],
|
||||
connectionId,
|
||||
AGENT_STATUS_LEGACY_UNADVERTISED_PEER_CAPABILITIES
|
||||
),
|
||||
// Why: the WSL relay protocol advertises no run-serving capability; stamped onto a copy so the
|
||||
// wire-deserialized notification object itself is never mutated.
|
||||
ingest: (envelope, connectionId) => {
|
||||
const capped = {
|
||||
...envelope,
|
||||
advertisedAgentStatusCapabilities: AGENT_STATUS_LEGACY_UNADVERTISED_PEER_CAPABILITIES
|
||||
}
|
||||
type IngestEnvelope = Parameters<typeof agentHookServer.ingestRemote>[0]
|
||||
// oxlint-disable-next-line typescript/consistent-type-assertions -- SAFETY: envelope is the wire-deserialized notification; ingestRemote independently re-validates paneKey's type before trusting anything here.
|
||||
return agentHookServer.ingestRemote(capped as IngestEnvelope, connectionId)
|
||||
},
|
||||
installHooks: installRemoteManagedAgentHooks,
|
||||
installCodex: (runtimeHomePath, distro) =>
|
||||
codexHookService.installForRuntimeHomeSerialized(runtimeHomePath, {
|
||||
|
||||
@@ -1607,10 +1607,11 @@ export class SshRelaySession {
|
||||
typeof envelope.claudeRunningNonAgentTask === 'boolean'
|
||||
? envelope.claudeRunningNonAgentTask
|
||||
: undefined,
|
||||
// Why: the SSH relay protocol advertises no run-serving capability.
|
||||
advertisedAgentStatusCapabilities: AGENT_STATUS_LEGACY_UNADVERTISED_PEER_CAPABILITIES,
|
||||
payload: envelope.payload
|
||||
},
|
||||
this.targetId,
|
||||
AGENT_STATUS_LEGACY_UNADVERTISED_PEER_CAPABILITIES
|
||||
this.targetId
|
||||
)
|
||||
})
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ export const AGENT_STATUS_PERSISTED_HYDRATION_MODE: AgentStatusLegacyAdmissionMo
|
||||
kind: 'persisted-hydration'
|
||||
})
|
||||
|
||||
/** Existing relay protocols advertise no run-serving capability. Production call sites pass this explicitly. */
|
||||
/** Existing relay protocols advertise no run-serving capability. Production ingress call sites stamp this onto the envelope explicitly. */
|
||||
export const AGENT_STATUS_LEGACY_UNADVERTISED_PEER_CAPABILITIES: readonly string[] = Object.freeze(
|
||||
[]
|
||||
)
|
||||
|
||||
@@ -116,8 +116,12 @@ describe('legacy agent-status ingress ratchet', () => {
|
||||
'main/agent-hooks/wsl-hook-relay-deps.ts',
|
||||
'main/ssh/ssh-relay-session.ts'
|
||||
])
|
||||
// Why: a bare import of the constant (unused elsewhere) would pass a substring check
|
||||
// without ever stamping it onto the envelope — require the actual key:value binding.
|
||||
for (const caller of callers) {
|
||||
expect(caller.source).toContain('AGENT_STATUS_LEGACY_UNADVERTISED_PEER_CAPABILITIES')
|
||||
expect(stripComments(caller.source)).toMatch(
|
||||
/advertisedAgentStatusCapabilities\s*:\s*AGENT_STATUS_LEGACY_UNADVERTISED_PEER_CAPABILITIES\b/
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
Reference in New Issue
Block a user