DEV Community

Jordan Huang
Jordan Huang

Posted on

The Box Has Your Repo. Not Your PATH.

Did you paste a repo into a remote box today? Did you treat that shell like your laptop?

I keep a short FAQ for that moment. It is not about raw model quality. It is about the machine under the prompt.

The box answers in a familiar prompt. Your files sit on its disk now. Git status can look almost honest here.

So which environment did you actually trust then?

Why this FAQ exists

Five claims keep showing up in agent chats. They sound careful. They are usually false.

The prompt looks local. The process is not local. That gap is where bad patches hide.

I do not debate the chat log first. I dump box identity first. Then I let the model touch files.

The five claims

  • "The box inherited my PATH."
  • "Locale and timezone match my laptop."
  • "SSH agent forwarding just works."
  • "My .env is present, or safely gone."
  • "Unix flags are just Unix flags."

Want a two minute counter-argument? Run the dump on both machines. Diff the reports. Keep secrets out of both files.

Artifact: box identity dump

This script is a proposed check. It is not a published benchmark. Inspect it before you run it.

#!/usr/bin/env bash
# box-identity.sh — proposed environment dump
# Label: unexecuted template. Read it before running.
set -euo pipefail

out="${1:-box-identity.txt}"

{
  echo "=== host ==="
  uname -a || true
  echo "id: $(id)"
  echo "pwd: $(pwd)"
  echo "home: ${HOME:-}"
  echo "shell: ${SHELL:-}"
  echo

  echo "=== path ==="
  printf '%s\n' "${PATH:-}" | tr ':' '\n'
  echo
  echo "which python3: $(command -v python3 || echo MISSING)"
  echo "which git: $(command -v git || echo MISSING)"
  echo "which ssh: $(command -v ssh || echo MISSING)"
  echo "which sed: $(command -v sed || echo MISSING)"
  echo "which date: $(command -v date || echo MISSING)"
  python3 -V 2>&1 || true
  git --version 2>&1 || true
  echo

  echo "=== locale and time ==="
  echo "date: $(date)"
  echo "date -u: $(date -u)"
  echo "TZ=${TZ:-unset}"
  echo "LANG=${LANG:-unset}"
  echo "LC_ALL=${LC_ALL:-unset}"
  locale 2>/dev/null || true
  echo

  echo "=== git ==="
  git rev-parse --show-toplevel 2>/dev/null || echo "not a git work tree"
  git config --show-origin --get user.name || true
  git config --show-origin --get user.email || true
  git remote -v || true
  git status -sb || true
  echo

  echo "=== ssh names only ==="
  echo "SSH_AUTH_SOCK=${SSH_AUTH_SOCK:-unset}"
  echo "SSH_AGENT_PID=${SSH_AGENT_PID:-unset}"
  if [[ -d "${HOME}/.ssh" ]]; then
    ls -l "${HOME}/.ssh" | awk '{print $1, $3, $4, $9}'
  else
    echo "no ~/.ssh directory"
  fi
  echo

  echo "=== userland probe ==="
  if echo 'a' | sed -E 's/a/b/' >/dev/null 2>&1; then
    echo "sed accepts -E"
  else
    echo "sed rejects -E"
  fi
  if date --version >/dev/null 2>&1; then
    echo "date looks GNU"
  else
    echo "date does not look GNU"
  fi
} >"$out"

echo "wrote $out"
Enter fullscreen mode Exit fullscreen mode

Run it on the laptop. Run it on the remote box. Store both files beside the repo, not in chat.

Notice what the script refuses to print. No key material. No .env values. No token files.

You want names, paths, and versions. You do not want a second leak. Would you paste printenv into a model thread?

FAQ 1: "The box inherited my PATH"

Claim: the agent uses your python3.

Evidence:

  • command -v python3 on the laptop
  • command -v python3 on the box
  • python3 -V on both sides

Corrected model: PATH is a process property. It does not ride with git clone. A free server boots its own image. That image has its own interpreter.

Would you debug imports against the wrong binary? I would not. If the model says it ran pytest, ask which file ran.

command -v pytest
python3 -c 'import sys; print(sys.executable); print(sys.version)'
Enter fullscreen mode Exit fullscreen mode

Two paths mean two worlds. Pin one before you trust a green line.

What the chat usually hides

The model quotes python3. Your brain fills in your python. The box never agreed to that mapping.

Virtualenv names can match too. The contents still differ. Same folder name, different wheels.

FAQ 2: "Locale and timezone match my laptop"

Claim: timestamps and sorts will match CI.

Evidence:

  • date and date -u
  • TZ, LANG, LC_ALL
  • one fixture that parses a local timestamp

Corrected model: locale is not in your repo. Timezone is not in package.json. A UTC box passes tests your laptop fails. The reverse happens too.

I treat date tests as environment tests. They are not pure functions. Did the agent "fix" flakes by changing locale? That is a hidden dependency, not a fix.

python3 - <<'PY'
import time, locale
print("tzname", time.tzname)
print("locale", locale.getlocale())
PY
Enter fullscreen mode Exit fullscreen mode

Who owns TZ in that process? You, or the image maintainer?

A cheap trap

String sorts change with LC_COLLATE. Snapshot tests then drift. The model "simplifies" the assertion. You ship a locale bug.

Set timezone in the test command. Do not set it in chat memory.

TZ=UTC LANG=C python3 -m pytest tests/test_clock.py
Enter fullscreen mode Exit fullscreen mode

FAQ 3: "SSH just works on the box"

Claim: git push from the agent is you.

Evidence:

  • SSH_AUTH_SOCK
  • name-only listing of ~/.ssh
  • git remote -v
  • git config user.email

Corrected model: a free server is a different principal. It may have no agent. It may have a key you did not mint. It may have nothing, then ask for a paste.

Do not paste a key. Do not enable forwarding because the prompt looked stuck. Who is origin expecting on that socket?

git remote -v
git config --show-origin --get user.email
echo "${SSH_AUTH_SOCK:-unset}"
Enter fullscreen mode Exit fullscreen mode

If the sock is unset, push is not you. If a key file exists, ask who created it.

This is not the committer-name myth. That myth is about user.email. This one is about transport identity. Commits and pushes can lie separately.

Push path I actually use

Draft on the box. Review the diff locally. Authenticated writes stay on my laptop. The box does not need my agent.

FAQ 4: "My .env is here, or safely gone"

Claim: gitignore means the model cannot see secrets. Or the opposite claim: the box loaded local env by magic.

Evidence:

  • whether .env exists on disk
  • whether process env has names you recognize
  • whether the model asked to cat it

Corrected model: gitignore is a git rule. It is not a memory fence. A file on disk is visible. A missing file is not safe. It is only missing.

Print names. Never print values.

python3 - <<'PY'
import os
keys = sorted(os.environ)
needles = ("KEY", "TOKEN", "SECRET", "PASSWORD", "DATABASE_URL")
interesting = [k for k in keys if any(s in k.upper() for s in needles)]
print("interesting names:", interesting)
print("count", len(keys))
PY
Enter fullscreen mode Exit fullscreen mode

I want the list of names. I do not want values in chat. If .env exists, treat it as hostile until you know the source.

Did you copy it? Did a prior session leave it? Did the model write a placeholder that looks real?

Two failure modes

  1. The file is absent, tests talk to the wrong host.
  2. The file is present, and now the chat can quote it.

Neither mode is "handled." Both need an explicit choice.

FAQ 5: "sed is sed, date is date"

Claim: a macOS one-liner will work unchanged.

Evidence:

  • sed -E versus sed -r
  • date --version versus BSD date
  • uname

Corrected model: the box is probably GNU userland. Your laptop might be BSD userland. Models mix both dialects in one patch.

"Works on my machine" becomes "works in the chat." Neither result is CI.

echo 'foo' | sed -E 's/foo/bar/' && echo "sed -E ok" || echo "sed -E failed"
date +%s
Enter fullscreen mode Exit fullscreen mode

If a patch uses sed -i '', which Unix is that? If a patch uses date -d, ask again.

Makefile edition

make recipes copy your muscle memory. They also copy your OS. Pin POSIX-safe flags, or detect the flavor in the recipe.

Decision table

Myth Cheap check If it fails
PATH followed me diff command -v python3 pin the interpreter in the task
Locale followed me diff date and LANG set TZ in the test command
SSH is me print SSH_AUTH_SOCK only do not push from the box
.env is handled list env names, not values keep secrets off the box
Unix flags match probe sed and date write POSIX or detect OS

Print the table once per box. Fill it. Reuse it when the image changes. Did any row stay blank?

Where a free model and free server fit

I use this when the task is cheap exploration. A free model can draft the dump script. A free server can run it off my laptop.

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

MonkeyCode provides free model access and a free server option. That pairing is convenient. Convenience is the myth engine.

The product does not teleport PATH. It does not inherit my SSH agent. It does not make GNU and BSD agree.

I still dump identity first. Then I let the model touch the tree. If you start a free remote box, pause. Run the dump before the first apply loop.

What this does not prove

This script is not a sandbox audit. It does not measure isolation. It does not prove the model cannot see a mounted secret.

It also does not prove tests are deterministic. It only shows the environment tests will feel. I do not claim timings. I do not claim quotas. I do not claim how long a box lasts.

Those numbers change. Your dump does not. Keep the dump next to the diff.

Who should not use this approach

Skip this if you need a signed builder SBOM. Skip this if policy forbids unknown remote shells. Skip this if the repo cannot leave your workstation.

Skip this if you planned to paste production credentials "for a minute." A free box is the wrong minute. Also skip the "just push from the box" shortcut.

Use your laptop for authenticated git writes. The remote box can still be useful. It should not become your identity.

Corrected mental model

The repo can move. Your environment does not. The prompt can look local. The process is remote.

The model can quote your file. The file still lives on someone else's layout. Ask one question before the first patch: which machine is speaking?

Then ask a second question. Which PATH, locale, and credentials did that machine boot with? Until those answers sit on disk, the chat is not evidence.

Top comments (0)