fix(ralph-loop): harden Oracle VERIFIED detection

Replace fragile regex text matching with structured detection for Oracle verification evidence.

- Add oracle-verification-detector.ts with parseOracleVerificationEvidence()

- Use structured parsing instead of multiple regex patterns

- Add comprehensive test coverage for edge cases

- Update completion-promise-detector.ts to use isOracleVerified()

- Update pending-verification-handler.ts to use structured extraction

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
YeonGyu-Kim
2026-04-08 13:24:50 +09:00
parent 0bf5dc2629
commit d490b4dc20
4 changed files with 370 additions and 15 deletions
@@ -1,7 +1,7 @@
import type { PluginInput } from "@opencode-ai/plugin"
import { log } from "../../shared/logger"
import { HOOK_NAME } from "./constants"
import { ULTRAWORK_VERIFICATION_PROMISE } from "./constants"
import { extractOracleSessionID, isOracleVerified } from "./oracle-verification-detector"
import type { RalphLoopState } from "./types"
import { handleFailedVerification } from "./verification-failure-handler"
import { withTimeout } from "./with-timeout"
@@ -11,13 +11,6 @@ type OpenCodeSessionMessage = {
parts?: Array<{ type?: string; text?: string }>
}
const ORACLE_AGENT_PATTERN = /Agent:\s*oracle/i
const TASK_METADATA_SESSION_PATTERN = /<task_metadata>[\s\S]*?session_id:\s*([^\s<]+)[\s\S]*?<\/task_metadata>/i
const VERIFIED_PROMISE_PATTERN = new RegExp(
`<promise>\\s*${ULTRAWORK_VERIFICATION_PROMISE}\\s*<\\/promise>`,
"i",
)
function collectAssistantText(message: OpenCodeSessionMessage): string {
if (!Array.isArray(message.parts)) {
return ""
@@ -67,12 +60,11 @@ async function detectOracleVerificationFromParentSession(
}
const assistantText = collectAssistantText(message)
if (!VERIFIED_PROMISE_PATTERN.test(assistantText) || !ORACLE_AGENT_PATTERN.test(assistantText)) {
if (!isOracleVerified(assistantText)) {
continue
}
const sessionMatch = assistantText.match(TASK_METADATA_SESSION_PATTERN)
const detectedOracleSessionID = sessionMatch?.[1]?.trim()
const detectedOracleSessionID = extractOracleSessionID(assistantText)
if (detectedOracleSessionID) {
return detectedOracleSessionID
}