mirror of
https://github.com/stablyai/orca.git
synced 2026-10-04 16:02:08 +00:00
fix(pty): validate evidence field types, not just verdicts, in the inspection-evidence reader
A foreign host can put any JSON in processEvidence. An observed verdict carrying a non-string processName rode through normalization into recognizeAgentProcess and counted toward the 'foreground is not a recognized agent' leg of the positive-exited gate; non-string unverifiable reasons were forwarded as-is. Out-of-type payloads now degrade to unverifiable (malformed-evidence reason), and non-string reasons fall back to 'unspecified'.
This commit is contained in:
@@ -52,6 +52,37 @@ describe('readPtyProcessInspectionEvidence normalization', () => {
|
||||
expect(evidence.children).toEqual({ verdict: 'unverifiable', reason: 'unspecified' })
|
||||
})
|
||||
|
||||
it('coerces an observed verdict with a non-string processName to unverifiable', () => {
|
||||
// A number here would flow into recognizeAgentProcess and count toward the
|
||||
// "foreground is not a recognized agent" leg — malformed foreign data must
|
||||
// never feed the positive-exited path.
|
||||
const evidence = readPtyProcessInspectionEvidence({
|
||||
foregroundProcess: null,
|
||||
hasChildProcesses: false,
|
||||
processEvidence: {
|
||||
foreground: { verdict: 'observed', processName: 42 } as never,
|
||||
children: { verdict: 'exited' }
|
||||
}
|
||||
})
|
||||
expect(evidence.foreground).toEqual({
|
||||
verdict: 'unverifiable',
|
||||
reason: 'malformed foreground inspection evidence'
|
||||
})
|
||||
})
|
||||
|
||||
it('replaces a non-string unverifiable reason instead of forwarding it', () => {
|
||||
const evidence = readPtyProcessInspectionEvidence({
|
||||
foregroundProcess: null,
|
||||
hasChildProcesses: false,
|
||||
processEvidence: {
|
||||
foreground: { verdict: 'unverifiable', reason: 42 } as never,
|
||||
children: { verdict: 'unverifiable', reason: { deep: true } } as never
|
||||
}
|
||||
})
|
||||
expect(evidence.foreground).toEqual({ verdict: 'unverifiable', reason: 'unspecified' })
|
||||
expect(evidence.children).toEqual({ verdict: 'unverifiable', reason: 'unspecified' })
|
||||
})
|
||||
|
||||
it('synthesizes the legacy reading when the host predates evidence', () => {
|
||||
expect(
|
||||
readPtyProcessInspectionEvidence({ foregroundProcess: 'codex', hasChildProcesses: true })
|
||||
|
||||
@@ -78,14 +78,24 @@ export function readPtyProcessInspectionEvidence(result: {
|
||||
}
|
||||
}
|
||||
|
||||
// Field types are validated, not just verdicts: a foreign host can put any
|
||||
// JSON in these slots, and an out-of-type payload must degrade to
|
||||
// `unverifiable` — never ride an `observed` verdict into the exit gate.
|
||||
function normalizeReason(reason: unknown): string {
|
||||
return typeof reason === 'string' ? reason : 'unspecified'
|
||||
}
|
||||
|
||||
function normalizeForegroundEvidence(
|
||||
evidence: PtyForegroundProcessEvidence | undefined
|
||||
): PtyForegroundProcessEvidence {
|
||||
if (evidence?.verdict === 'observed') {
|
||||
return { verdict: 'observed', processName: evidence.processName ?? null }
|
||||
const processName = evidence.processName ?? null
|
||||
if (processName === null || typeof processName === 'string') {
|
||||
return { verdict: 'observed', processName }
|
||||
}
|
||||
}
|
||||
if (evidence?.verdict === 'unverifiable') {
|
||||
return { verdict: 'unverifiable', reason: evidence.reason ?? 'unspecified' }
|
||||
return { verdict: 'unverifiable', reason: normalizeReason(evidence.reason) }
|
||||
}
|
||||
return { verdict: 'unverifiable', reason: 'malformed foreground inspection evidence' }
|
||||
}
|
||||
@@ -97,7 +107,7 @@ function normalizeChildrenEvidence(
|
||||
return { verdict: evidence.verdict }
|
||||
}
|
||||
if (evidence?.verdict === 'unverifiable') {
|
||||
return { verdict: 'unverifiable', reason: evidence.reason ?? 'unspecified' }
|
||||
return { verdict: 'unverifiable', reason: normalizeReason(evidence.reason) }
|
||||
}
|
||||
return { verdict: 'unverifiable', reason: 'malformed child-process inspection evidence' }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user