DEV Community

Jordan Huang
Jordan Huang

Posted on

FAQ: Path Myths Your Agent Loop Still Believes

Did your agent actually start in the repository root?

I keep seeing that claim in chat logs. Then a relative path writes into /tmp. Painful, right?

Why this FAQ exists

Agent loops hide the working directory on purpose. The model narrates. The shell stays quiet.

I wanted a checklist I could rerun. Not another confidence speech.

Disclosure: This article was prepared as part of MonkeyCode's product outreach.

I run this checklist on a second machine. I use MonkeyCode's free model access there. The free server option is that second box. Treat it like a stranger laptop, not a clone of yours.

Delete the product name tomorrow. These path myths still bite.

The corrected mental model

A sentence about paths is a claim. pwd is a measurement.

I write a fingerprint file first. I diff that file second. I trust chat last.

This workflow is proposed. I am not reporting unpublished timings. I am not inventing quotas or hardware.

Myth 1: The chat said "repo root," so we were there

Why does this survive? Because the wording sounds operational.

It is not operational. It is prose wearing a hard hat.

Measure three strings before you edit files:

git rev-parse --show-toplevel
pwd
python -c "import os; print(os.getcwd())"
Enter fullscreen mode Exit fullscreen mode

If those strings disagree, halt. Do not "just apply the patch."

Corrected model: the transcript is testimony. The shell is the court.

Myth 2: A remote server shares my laptop paths

Home directories feel portable. They are not.

macOS paths die on Linux. Drive letters die even faster. Your IDE's absolute path is a trap.

Ask a blunt question. Would /Users/you/src/app exist on a borrowed host?

Proposed one-liner, labeled unexecuted until you run it:

# proposed fingerprint snippet, not a production SLA
import os, json, pathlib, socket, time, sys

payload = {
    "cwd": os.getcwd(),
    "home": str(pathlib.Path.home()),
    "user": os.environ.get("USER") or os.environ.get("USERNAME"),
    "host": socket.gethostname(),
    "platform": sys.platform,
    "sep": os.sep,
    "pid": os.getpid(),
    "utc": time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime()),
}
print(json.dumps(payload, indent=2))
Enter fullscreen mode Exit fullscreen mode

Run it on your laptop. Run it on the free server. Diff the two JSON files.

That delta is the real architecture diagram. Chat never draws it.

Myth 3: Every prompt starts from a clean cwd

Does your loop reuse a shell? Be honest.

A reused shell remembers cd. It remembers export. It remembers a broken venv.

Leftover files are state. State is a bug farm.

Proposed test plan. No pass-rate theater attached:

  1. Open one long-lived shell for the agent.
  2. Run cd /tmp && echo leak > marker.txt.
  3. Send a fresh prompt: list project files only.
  4. Check whether marker.txt is visible.
  5. Print pwd before the prompt and after it.

If marker.txt shows up, cwd leaked. Your "new task" is not new.

Corrected model: treat cwd like a database transaction. Commit it or reset it.

Myth 4: Relative paths are enough, so skip fingerprints

Relative paths work after you pin the root. Before that, they gamble.

I want a file on disk. I do not want a paragraph.

Put the fingerprint next to the patch. Review both in the same glance.

# proposed layout
mkdir -p .agent
python env_fingerprint.py > .agent/env_fingerprint.json
git rev-parse HEAD > .agent/head.txt
diff -u .agent/env_fingerprint.local.json .agent/env_fingerprint.remote.json
Enter fullscreen mode Exit fullscreen mode

No fingerprint, no merge. That rule is cheap. Path bugs are not.

Myth 5: Cheap tokens mean environment checks are optional

Free models do not fix POSIX. Free servers do not clone your $PATH.

Two machines means two clocks. Two path separators. Two leftover workspaces.

The cheaper the loop, the more often you rerun it. Reruns multiply path mistakes.

Corrected model: cost is a budget choice. Fingerprints are a correctness choice.

Artifact: env_fingerprint.py

Here is a small proposed script. Run it before you trust any relative edit.

#!/usr/bin/env python3
"""Write a tiny environment fingerprint for agent loops."""
from __future__ import annotations

import json
import os
import pathlib
import platform
import socket
import subprocess
import sys
import time


def git(cmd: list[str]) -> str | None:
    try:
        out = subprocess.check_output(
            ["git", *cmd],
            stderr=subprocess.DEVNULL,
            text=True,
        )
        return out.strip() or None
    except (OSError, subprocess.CalledProcessError):
        return None


def main() -> None:
    repo = git(["rev-parse", "--show-toplevel"])
    head = git(["rev-parse", "HEAD"])
    cwd = pathlib.Path(os.getcwd()).resolve()
    repo_path = pathlib.Path(repo).resolve() if repo else None
    payload = {
        "cwd": str(cwd),
        "repo_toplevel": repo,
        "head": head,
        "cwd_is_repo": bool(repo_path and cwd == repo_path),
        "home": str(pathlib.Path.home()),
        "user": os.environ.get("USER") or os.environ.get("USERNAME"),
        "host": socket.gethostname(),
        "platform": platform.platform(),
        "python": sys.version.split()[0],
        "sep": os.sep,
        "path_entries": os.environ.get("PATH", "").split(os.pathsep)[:8],
        "tz": list(time.tzname),
        "utc": time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime()),
        "pid": os.getpid(),
        "ppid": os.getppid() if hasattr(os, "getppid") else None,
    }
    out_dir = pathlib.Path(".agent")
    out_dir.mkdir(exist_ok=True)
    out = out_dir / "env_fingerprint.json"
    out.write_text(json.dumps(payload, indent=2) + "\n", encoding="utf-8")
    print(out.read_text(encoding="utf-8"))


if __name__ == "__main__":
    main()
Enter fullscreen mode Exit fullscreen mode

How I wire it into a loop:

python env_fingerprint.py
# later, on the other host
python env_fingerprint.py > /tmp/remote.json
diff -u .agent/env_fingerprint.json /tmp/remote.json
Enter fullscreen mode Exit fullscreen mode

Read the diff out loud. Then decide whether relative paths are sane.

Decision table

Chat claim Measure this Fail the step when
"We are in the repo root" cwd vs repo_toplevel They differ after resolve
"Same machine as last turn" pid, host, utc Host changed with no note
"Clean workspace" leftover marker file Marker still exists
"This path works everywhere" sep, home, platform Absolute path from another OS
"The patch landed here" fingerprint beside the diff Fingerprint file missing

Print the table in the PR. Reviewers need it more than the model does.

A tiny pytest guard (also proposed)

# test_env_fingerprint.py — proposed local guard
import json
from pathlib import Path


def test_fingerprint_cwd_matches_repo():
    data = json.loads(Path(".agent/env_fingerprint.json").read_text())
    assert data["repo_toplevel"], "git toplevel missing"
    assert data["cwd_is_repo"] is True
Enter fullscreen mode Exit fullscreen mode

This test does not prove the agent was smart. It proves the agent stood in the repo.

Is that a low bar? Yes. Miss it anyway and patches land in the wrong tree.

Limitations

This fingerprint is shallow. It ignores container mounts. It ignores NFS root squashing. It ignores Windows drive mapping beyond os.sep.

It does not freeze package versions. Use a lockfile for that job. It does not prove the model told the truth about tests.

Clocks can skew. Hostnames can collide. PATH is truncated to eight entries on purpose.

If your agent runs inside Docker, fingerprint the container. Fingerprinting only the hypervisor still lies to you.

Who should not use this approach

Skip this if you already have hermetic builders. Bazel users, Nix users, you are already ahead.

Skip this for production deploys. A JSON file is not a signed provenance record.

Skip this if the agent cannot execute local commands. Then you have a bigger problem.

Do not park secrets on a free remote server. Fingerprints can leak $HOME and usernames. Redact before you paste anything.

What I do after the diff

I keep three files beside every agent patch:

  • .agent/env_fingerprint.json
  • .agent/head.txt
  • the unified diff of local versus remote fingerprints

If the diff is noisy, I refuse the patch. Harsh? Maybe. Path bugs are harsher.

Still think the chat log is pwd? Run the script once. Then tell me which myth survived.

Top comments (0)