{"record":{"id":"3c5c3c7595e69cfb","repo":"abhigyanpatwari/GitNexus","slug":"evidence-source-must-be-a-regular-non-symlink-file","errorCode":null,"errorMessage":"evidence source must be a regular non-symlink file: {path}","messagePattern":"evidence source must be a regular non-symlink file: (.+?)","errorType":"exception","errorClass":"SandboxError","httpStatus":null,"severity":"error","filePath":"eval/workflow_bench/evolve.py","lineNumber":281,"sourceCode":"  gitnexus/test/unit/skills-steering.test.ts before rewording any command.\n- Never weaken the skills' hard gates: impact-before-edit,\n  detect_changes-before-commit, foreground verification.\n- Keep the edit small — a rule added, sharpened, or deleted; a budget\n  adjusted; a phase reordered. A sprawling rewrite loses in human review even\n  if it wins the gate.\n\nFinally write {proposal_path}: the failure pattern (cite task/arm/session\nids), the single change you made, the metric you expect to move and why, and\nthe risks. That file is the reviewer-facing case for the candidate.\"\"\"\n\n\n# ─── Proposer session ────────────────────────────────────────────────────────\n\n\ndef _bounded_regular_text(path: Path, limit: int = MAX_EVIDENCE_FILE_BYTES) -> str:\n    mode = path.lstat().st_mode\n    if path.is_symlink() or not stat.S_ISREG(mode):\n        raise SandboxError(f\"evidence source must be a regular non-symlink file: {path}\")\n    with path.open(\"rb\") as handle:\n        if path.stat().st_size > limit:\n            handle.seek(-limit, os.SEEK_END)\n        return handle.read(limit).decode(errors=\"replace\")\n\n\ndef _real_results_root(results_dir: Path) -> Path:\n    root = results_dir.expanduser().absolute()\n    try:\n        metadata = root.lstat()\n    except OSError as exc:\n        raise SandboxError(f\"results directory is unavailable: {root}: {exc}\") from exc\n    if stat.S_ISLNK(metadata.st_mode) or not stat.S_ISDIR(metadata.st_mode):\n        raise SandboxError(f\"results directory must be a real non-symlink directory: {root}\")\n    if root.resolve(strict=True) != root:\n        raise SandboxError(f\"results directory must not traverse symlinks: {root}\")\n    return root\n","sourceCodeStart":263,"sourceCodeEnd":299,"githubUrl":"https://github.com/abhigyanpatwari/GitNexus/blob/d540b00184d71a896261ee02670da9a92d59d8f7/eval/workflow_bench/evolve.py#L263-L299","documentation":"_bounded_regular_text reads an evidence file (patch, redacted excerpt) into the proposer prompt. It lstat's the path and refuses symlinks (path.is_symlink()) and any non-regular file (not stat.S_ISREG). The guard prevents a crafted results tree from redirecting the read through a symlink to an arbitrary host file before it crosses the sandbox trust boundary.","triggerScenarios":"An evidence file under the staged evidence dir is a symlink (e.g. `ln -s /etc/passwd patch.diff`), a broken symlink, or a special file; a packaging step symlinked shared excerpts.","commonSituations":"Shared redacted excerpts reused across runs via symlinks; a proposer or upstream tool that symlinks outputs into the evidence dir; broken symlinks after the evidence root was moved.","solutions":["Locate the offending entry: `find <evidence_dir> -type l`.","Materialize it: `cp -L --remove-destination <link> <link>`.","Regenerate the evidence bundle so it contains only regular files."],"exampleFix":"# before\nln -s /shared/excerpts/run-42.patch evidence/run-42.patch\n_bounded_regular_text(Path(\"evidence/run-42.patch\"))\n\n# after\ncp /shared/excerpts/run-42.patch evidence/run-42.patch\n_bounded_regular_text(Path(\"evidence/run-42.patch\"))","handlingStrategy":"validation","validationCode":"import stat\nfrom pathlib import Path\n\ndef evidence_file_is_regular(path: Path) -> bool:\n    mode = path.lstat().st_mode\n    return not path.is_symlink() and stat.S_ISREG(mode)\n\n# before reading evidence\nfor f in evidence_dir.rglob(\"*\"):\n    if f.is_file() and not evidence_file_is_regular(f):\n        raise ValueError(f\"non-regular evidence file: {f}\")","typeGuard":"import stat\nfrom pathlib import Path\n\ndef is_safe_evidence_file(path: Path) -> bool:\n    return path.exists() and not path.is_symlink() and stat.S_ISREG(path.lstat().st_mode)","tryCatchPattern":null,"preventionTips":["Generate evidence with copies, never symlinks.","Audit `find <evidence_dir> -type l` in CI; it must be empty.","Materialize any shared excerpt with cp -L --remove-destination before staging."],"tags":["workflow-bench","sandbox","security","filesystem","symlink","evidence"],"backgroundTag":null,"analyzedSha":"d540b00184d71a896261ee02670da9a92d59d8f7","analyzedAt":"2026-08-12T19:50:25.132Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}