{"record":{"id":"feaebba202e2017a","repo":"abhigyanpatwari/GitNexus","slug":"oracle-stage-parent-changed-during-verification","errorCode":null,"errorMessage":"oracle stage parent changed during verification: {item.target}","messagePattern":"oracle stage parent changed during verification: (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"critical","filePath":"eval/workflow_bench/oracle_assets.py","lineNumber":501,"sourceCode":"            view = view[written:]\n        os.fchmod(descriptor, 0o400)\n        os.fsync(descriptor)\n    finally:\n        os.close(descriptor)\n\n\ndef _verify_staged_oracle(stage_root: Path, snapshot: TaskOracleSnapshot) -> None:\n    root_metadata = stage_root.lstat()\n    if stat.S_ISLNK(root_metadata.st_mode) or not stat.S_ISDIR(root_metadata.st_mode):\n        raise ValueError(\"oracle stage root changed during verification\")\n    for item in snapshot.files:\n        relative = PurePosixPath(item.target)\n        current = stage_root\n        for part in relative.parts[:-1]:\n            current /= part\n            metadata = current.lstat()\n            if stat.S_ISLNK(metadata.st_mode) or not stat.S_ISDIR(metadata.st_mode):\n                raise ValueError(f\"oracle stage parent changed during verification: {item.target}\")\n        observed = _read_oracle_file(stage_root, relative)\n        if observed != item.payload:\n            raise ValueError(f\"oracle file changed during verification: {item.target}\")\n\n\n@contextmanager\ndef staged_task_oracle(worktree: Path, snapshot: TaskOracleSnapshot) -> Iterator[Path]:\n    \"\"\"Materialize a private random oracle root only after the model exits.\"\"\"\n\n    root = worktree.expanduser().absolute()\n    metadata = root.lstat()\n    if stat.S_ISLNK(metadata.st_mode) or not stat.S_ISDIR(metadata.st_mode) or root.resolve(strict=True) != root:\n        raise ValueError(f\"oracle worktree must be a real non-symlink directory: {root}\")\n    stage_root = root / f\".wfbench-oracle-{secrets.token_hex(16)}\"\n    stage_root.mkdir(mode=0o700)\n    stage_root.chmod(0o700)\n    primary: BaseException | None = None\n    try:","sourceCodeStart":483,"sourceCodeEnd":519,"githubUrl":"https://github.com/abhigyanpatwari/GitNexus/blob/d540b00184d71a896261ee02670da9a92d59d8f7/eval/workflow_bench/oracle_assets.py#L483-L519","documentation":"Same verification pass as error 360, but per-parent-directory: while walking the parents of each staged oracle file (relative.parts[:-1]), every intermediate directory must still be a real directory. A symlink or non-dir parent means the staged path was restructured mid-verification. The harness aborts rather than emit an untrusted result.","triggerScenarios":"Triggered inside _verify_staged_oracle's parent walk when any intermediate `current /= part` resolves to a symlink or non-directory. Common when a deep oracle path like `a/b/c/d.txt` has had `a` or `b` replaced after staging.","commonSituations":"An agent under test replaces a directory with a symlink to escape the sandbox; a symlink-based mirror of the worktree; concurrent git operations (checkout/clone) inside the worktree; running on a filesystem with case-folding collisions.","solutions":["Use the {item.target} in the message to identify the affected oracle file, then inspect each parent segment under stage_root with `ls -la` / `readlink`.","Ensure the worktree is on a real local directory and no other process is mutating it during the run.","Audit the agent under test for symlink creation or directory replacement inside the oracle stage path.","Re-stage from a fresh clone and re-run."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"# Verify every parent of every oracle target is a real dir before staging.\nimport stat\nfrom pathlib import Path, PurePosixPath\n\ndef precheck_parents(stage_root: Path, targets: list[str]) -> None:\n    for t in targets:\n        cur = stage_root\n        for part in PurePosixPath(t).parts[:-1]:\n            cur /= part\n            # Parents don't have to exist yet (the harness mkdir's them), but if\n            # they DO exist they must be real directories.\n            try:\n                st = cur.lstat()\n            except FileNotFoundError:\n                continue\n            assert stat.S_ISDIR(st.st_mode) and not stat.S_ISLNK(st.st_mode), \\\n                f'{cur} is not a real directory'","typeGuard":null,"tryCatchPattern":"try:\n    with staged_task_oracle(worktree, snapshot) as stage:\n        ...\nexcept ValueError as exc:\n    if 'stage parent changed' in str(exc):\n        log.security('oracle parent replaced mid-run: %s', exc)\n        invalidate_run()\n    raise","preventionTips":["Ensure no concurrent process can create symlinks inside the worktree during the run.","Run on local disk; avoid overlay/sync filesystems.","Audit the agent under test for any symlink creation under the worktree."],"tags":["oracle","toctou","symlink","integrity","benchmark"],"backgroundTag":null,"analyzedSha":"d540b00184d71a896261ee02670da9a92d59d8f7","analyzedAt":"2026-08-12T19:50:25.132Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}