DEV Community

Jordan Huang
Jordan Huang

Posted on

The Model Does Not Index Your Repo: Five Context Myths

Does your coding agent actually know this codebase?
I hear that claim in almost every review.
Someone pastes a tree, then trusts the answer.

That misplaced trust is the actual bug.
A path in a prompt is not a read.
A long context window is not an index.

This FAQ is about five repo-context myths.
Each myth has a local check you can run.
Each myth also has a tighter mental model.

I also include a small bundle script below.
Run it on a dirty git tree.
Keep the model strictly inside that bundle.

Why this keeps shipping broken reviews

Have you ever watched a model invent a helper?
The helper "lives" in a file nobody sent.
The review still sounds confident, yet the patch applies.

Raw confidence is not the same as coverage.
Coverage means an explicit file list, period.
If the file is missing, the claim is fiction.

I treat every remote pass as stateless.
I curate a bundle and record the hashes.
I reject findings that cite missing paths.

Disclosure: This article was prepared as part of MonkeyCode's product outreach.
I use MonkeyCode free models on the free server.

That pass reviews the hashed bundle only.
I do not treat that server as my laptop checkout.

Myth 1: A mentioned path means the file was read

Someone writes a review note saying see src/auth.ts.
The model then talks about validateSession anyway.
Did anyone actually attach those file bytes?

You should ask a much sharper question.
Was the file in the request body?
Can you hash what left your machine?

If you cannot hash it, you did not send it.
Mentioning a path is a hint, not I/O.
Hints do not load disks on their own.

Here is the corrected model for this myth.
Only bytes inside the bundle actually exist.

Cite paths from the manifest, never from memory.
Drop findings that name files outside the list.

Local check

git diff --name-only HEAD
git status --porcelain
Enter fullscreen mode Exit fullscreen mode

Those commands only list candidate files locally.
They do not upload anything by themselves.
Your next step is a strict allowlist.

Myth 2: A bigger window is a search index

Context windows grew, but so what now?
A window is a buffer, not grep.
It does not rank files in your monorepo.

Do you search production using only cat?
Then stop dumping twenty packages at once.
The model will skim and latch onto noise.

Here is the corrected model for windows.
Context is a scarce working set you choose.

Retrieval stays on your side of the cable.
You pick files, cap bytes, and then move on.

Local check

wc -c $(git diff --name-only HEAD)
Enter fullscreen mode Exit fullscreen mode

If the byte count explodes, you are not reviewing.
At that point you are gambling on attention.
Split the diff by package or by concern.

Myth 3: One long chat equals architecture knowledge

Did that chat session start yesterday afternoon?
Then people say the model knows the system.
A chat log is not a domain model.

Did you rotate onto a free server again?
Did the long thread summarize itself overnight?
Those summaries drop the sharp edges first.

Here is the corrected model for sessions.
Each remote call is a brand new reader.

Pass the architecture notes you actually need.
Do not assume leftover memory still exists.

I keep a short ARCHITECTURE.md excerpt in the bundle.
I keep it under a hard byte cap.
I update it when the diff touches boundaries.

Myth 4: The free remote disk is your working tree

This particular myth is sneakier than it looks.
A free server can still run some commands.
That does not make it your laptop.

Is your dirty local file even there?
Is your ignored env file sitting there too?
Is main even pointing at the same commit?

Here is the corrected model for remote disks.
Remote state stays untrusted and fully ephemeral.

Git on your machine is the source of truth.
The server sees a snapshot you uploaded, nothing else.

Never point that remote pass at secrets.
Never let that server become git origin.
Never use it as the only copy of a patch.

Myth 5: A file tree proves the model covered the repo

A generated file tree looks thorough at first.
That tree is a map, not the territory.
The model can quote a path and still guess the body.

Tree output mostly trains a confident tone.
It still does not load the implementations.
It also leaks private folder names in logs.

Here is the corrected model for trees.
Trees are optional indexes for you, not the model.

Send file bodies for the actual review scope.
If the body is absent, treat the comment as speculation.

The artifact: a review bundle you can hash

Here is the workflow I actually run.
It is small, boring, and fully checkable.

  1. Collect the file names from git diff.
  2. Drop secrets and other generated junk files.
  3. Cap the total payload bytes with a budget.
  4. Write a manifest that includes sha256.
  5. Ask for JSON findings against that manifest.
  6. Reject any path not in the manifest.

This is a proposed local script, not magic.
Review that file before you run it.

#!/usr/bin/env python3
"""Build a hashed review bundle from the current git diff.

Proposed local helper. Edit the deny list before use.
"""
from __future__ import annotations

import hashlib
import json
import subprocess
import sys
from pathlib import Path

MAX_TOTAL_BYTES = 80_000
MAX_FILE_BYTES = 20_000
DENY_SUFFIXES = {".env", ".pem", ".key", ".p12", ".lock"}
DENY_NAMES = {".env", ".env.local", "id_rsa", "credentials.json"}


def git_names() -> list[str]:
    out = subprocess.check_output(
        ["git", "diff", "--name-only", "HEAD"],
        text=True,
    )
    return [line.strip() for line in out.splitlines() if line.strip()]


def denied(path: str) -> bool:
    p = Path(path)
    if p.name in DENY_NAMES:
        return True
    if p.suffix in DENY_SUFFIXES:
        return True
    parts = {part.lower() for part in p.parts}
    return bool(parts & {"secrets", ".ssh", ".aws"})


def sha256(data: bytes) -> str:
    return hashlib.sha256(data).hexdigest()


def main() -> int:
    files = []
    total = 0
    skipped = []
    for rel in git_names():
        if denied(rel):
            skipped.append({"path": rel, "reason": "denied"})
            continue
        path = Path(rel)
        if not path.is_file():
            skipped.append({"path": rel, "reason": "missing"})
            continue
        data = path.read_bytes()
        if len(data) > MAX_FILE_BYTES:
            skipped.append({"path": rel, "reason": "too_large"})
            continue
        if total + len(data) > MAX_TOTAL_BYTES:
            skipped.append({"path": rel, "reason": "budget"})
            continue
        total += len(data)
        files.append(
            {
                "path": rel,
                "sha256": sha256(data),
                "bytes": len(data),
                "text": data.decode("utf-8", errors="replace"),
            }
        )
    bundle = {
        "commit": subprocess.check_output(
            ["git", "rev-parse", "HEAD"], text=True
        ).strip(),
        "total_bytes": total,
        "files": files,
        "skipped": skipped,
    }
    Path("review_bundle.json").write_text(
        json.dumps(bundle, indent=2),
        encoding="utf-8",
    )
    print(f"wrote review_bundle.json with {len(files)} files, {total} bytes")
    return 0


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

That script does not call a model.
It only writes review_bundle.json on disk.
You can commit the manifest without the file bodies.

Strip the bodies before you log anything public.

python3 - <<'PY'
import json
from pathlib import Path
raw = json.loads(Path("review_bundle.json").read_text())
for item in raw["files"]:
    item.pop("text", None)
Path("review_manifest.json").write_text(json.dumps(raw, indent=2))
print("wrote review_manifest.json")
PY
Enter fullscreen mode Exit fullscreen mode

Now you finally have checkable evidence on disk.
The model may only cite files[].path.
Anything else stays strictly out of scope.

Decision table

Use this table before you paste anything remote.

Situation Send to a free remote pass? Why
Small git diff, no secrets Yes, as a hashed bundle Scope is explicit
Explain the whole service No Window is not an index
Env files or key material Never Remote disk is not your vault
Generated lockfile only Usually no Noise crowds out the diff
Architecture across packages Split into two bundles Keep a working set
Need a durable workspace Stay local Free servers are not origin

Prompt skeleton against the bundle

Do not improvise the instructions every single time.
Pin the rules next to the manifest.

You are reviewing ONLY the files in review_bundle.json.
If a path is not in files[].path, you must not cite it.
Return JSON only:
{
  "findings": [
    {
      "path": "string from manifest",
      "sha256": "must match files[].sha256",
      "severity": "low|medium|high",
      "claim": "one sentence",
      "quote": "verbatim substring from that file"
    }
  ]
}
If you lack evidence, return {"findings": []}.
Enter fullscreen mode Exit fullscreen mode

Then verify every quote on your local bundle.

#!/usr/bin/env python3
"""Reject findings that drift off the hashed bundle."""
import json
from pathlib import Path

bundle = json.loads(Path("review_bundle.json").read_text())
result = json.loads(Path("model_findings.json").read_text())
index = {f["path"]: f for f in bundle["files"]}

errors = []
for item in result.get("findings", []):
    path = item.get("path")
    if path not in index:
        errors.append(f"unknown path: {path}")
        continue
    if item.get("sha256") != index[path]["sha256"]:
        errors.append(f"hash mismatch: {path}")
        continue
    quote = item.get("quote") or ""
    if quote not in index[path]["text"]:
        errors.append(f"quote not in file: {path}")

if errors:
    raise SystemExit("\n".join(errors))
print("findings stayed inside the bundle")
Enter fullscreen mode Exit fullscreen mode

That last file is the real gate.
No quote means you drop the finding.
No hash match means you drop it too.

A one-hour test plan

Label this as a plan, not a published benchmark.

  1. Dirty exactly one source file on purpose.
  2. Run the bundle script on that tree.
  3. Confirm that secret files were skipped locally.
  4. Send only review_bundle.json to the model.
  5. Save the raw JSON as model_findings.json.
  6. Run the verifier against both JSON files.
  7. Insert a fake path and confirm the verifier fails.
  8. Change one source byte and confirm the hash fails.

If step seven does not fail, your gate is theater.
Fix the verifier before you trust a comment.

Limitations

This will not replace a human review.
It will not magically index a whole monorepo.
It will not keep state between calls.

Free model access still varies in output quality.
The free server is not a staging org.
I am not claiming latency numbers here.

JSON-shaped answers still drift without a gate.
That is why quotes and hashes matter.
If the model cannot quote, drop the row.

Large binary diffs stay out of this workflow.
Image-heavy pull requests are out as well.
So are incident response threads with customer data.

Who should not use this

Skip this if you cannot list the files.
Skip this if the diff is mostly secrets.
Skip this if policy forbids any remote source.

Skip this if you need a long-lived remote IDE.
This workflow assumes a snapshot, then a delete.
Your laptop remains the only working tree.

Skip this if you want architectural prophecy instead.
A bounded bundle cannot invent missing modules.
Ask a human who owns the boundary instead.

The mental model I keep

The model is a reviewer of a tarball.
That hashed tarball is the actual product.
Git remains the only system of record.

So, does the model have your repo?
It has only the bytes you hashed.
Everything else is just a confident story.

Top comments (0)