DEV Community

Sam Chen
Sam Chen

Posted on

The Transcript Looked Done. You Still Have No Receipt.

A clean transcript is not a review record. I want a local receipt before any free session touches my branch. If that receipt is empty, I do not share the work.

Does a confident last reply count as proof? No, I keep seeing summaries outrun the diff. The chat can sound finished while the tree is still a guess.

The hole I am naming

I am not repeating my older stop-loop note. I am not repeating the allowlist note either. This catalog is about the transcript you keep after the model goes quiet.

A transcript is only a story of tokens. A review record is a set of files you can rerun. I mix those two views when I am tired.

Do you mix those two views as well? Yes, I still catch it in late reviews. A receipt is how I catch that mix.

Free model access makes another turn feel cheap. A free server makes a scratch run feel disposable. Cheap and disposable are not the same as checked.

I still need the receipt on my laptop. No news page was attached to this draft. I will not invent a headline, a score, or a quota.

If a number is missing here, that is on purpose. Stale product figures can waste a whole sprint. I would rather show the check than a stale number.

What sits in the receipt

I keep four files next to the diff. They are plain text, and they are boring. Boring is what I want on a Friday merge.

  • prompt.txt holds the exact text I am willing to send.
  • claim-ledger.txt maps each claim to a file and a command.
  • replay.txt stores the command, the exit line, and a log hash.
  • receipt.sha256 names those files so a later edit is obvious.

None of these files makes the model correct. They make my shortcut visible to a reviewer. That is the whole point of this catalog.

Anti-pattern 1: The summary replaces the diff

Symptom

The pull request text is the model's closing paragraph. Reviewers reply to tone, and nobody names a line. The bug can hide under a smooth ending.

Root cause

The chat is ordered by time, and the diff is not. I let the easier view win the review. Have you merged a paragraph you never opened?

Replacement

I write the ledger before I open the request. Each claim points at one path and one check. If I cannot point, I delete the claim.

claim: empty names are rejected
file: src/parser.py
check: python -m unittest tests.test_parser
Enter fullscreen mode Exit fullscreen mode

Ask yourself this before you paste a summary. Can a teammate run the check without opening the chat? If the answer is no, the summary is still a story.

Anti-pattern 2: Price becomes a privacy control

Symptom

A key, a customer id, or a raw trace sits in the prompt. The word free made that paste feel small. A small paste can still become a large leak.

Root cause

I treated a billing label as a safety boundary. A billing label does not redact my files. Who told me that price was a control?

Nobody told me that, and I just hoped. Hope does not redact a prompt file either. I still have to run the search myself.

Replacement

I run a loud search before I send anything. This is not a full secret scanner at all. It catches the obvious leaks I keep repeating.

# proposal - unexecuted in this article
rg -n -i 'api[_-]?key|secret|password|BEGIN ' prompt.txt
Enter fullscreen mode Exit fullscreen mode

A hit means I stop and rewrite the sample. I use fake values instead of live ones. I never send a live token into a free model box.

Someone with a mandated scanner should keep that scanner. Do not swap a policy tool for one search line. This pattern is a tripwire, not a program of record.

Anti-pattern 3: The model invents a missing field

Symptom

A tool blob lacks a key the patch still uses. The chat then fills that gap in prose. The code branches on a field nobody returned.

Root cause

I trusted the shape I hoped to see. I did not pin the shape I actually got. Hope is not a schema I can ship.

Replacement

I record observed keys, and I leave gaps empty. I do not ask the model to invent fields. A missing key means stop, then a fresh command.

# proposal, not a captured production trace
tool: repo.status
observed_keys: [branch, dirty]
missing_keys: [ahead]
action: stop
Enter fullscreen mode Exit fullscreen mode

If the action line says stop, I do not merge. I fetch status with a command I can read. Then I edit that status note by hand.

Anti-pattern 4: Comments stand in for a test

Symptom

The diff is mostly comments and renamed variables. The claim says bugfix, but the test hash did not move. The chat still calls that change a fix.

Root cause

Comments feel like progress inside a long chat. Tests feel like friction, so the feeling wins. I refuse that trade on any branch I share.

Replacement

A bugfix claim must name a test path. Same hash as yesterday means the claim is void. I either write the test or I drop the label.

# proposal - unexecuted here
sha256sum tests/test_parser.py
git diff --stat -- tests/test_parser.py
Enter fullscreen mode Exit fullscreen mode

Which of those two did I actually finish? The saved hash will answer that question cleanly. A feeling in the chat will not answer it.

Anti-pattern 5: Yesterday's log becomes the prompt

Symptom

I resend the full chat so the next turn has context. The prompt then holds dead ends and reversed decisions. Old secrets can ride back in with that log.

Root cause

I used the provider as my working notebook. The provider is not my system of record. A free model will not remember my correction for me.

Replacement

I keep a twenty-line digest instead of the novel. The digest lists the decision and the rejected option. I hash it, and I send the digest only.

decision: reject empty names in parser
rejected: coerce empty names to guest
ledger: claim-ledger.txt
stop: do not add a network call
Enter fullscreen mode Exit fullscreen mode

Would I want that digest in the repo later? If I would not, I should not send the longer log. The longer log is how old mistakes return.

The order I follow

I follow the same order on every branch. I do not reorder it because a session feels friendly. A friendly session is still not a receipt.

  1. I write prompt.txt with fake sample values only.
  2. I write the claim ledger before I ask for a patch.
  3. I run the redaction search and stop on any hit.
  4. I ask for a patch only after those files exist.
  5. I save the command and the exit line in the replay file.
  6. I run the receipt script and read every bad exit.
  7. I read the diff myself before I share the branch.

That order is the replacement pattern for this catalog. Each step leaves a file or an exit code. If a step has neither, I am still in the anti-pattern.

The check I run before a share

Here is the bundle I keep beside the branch. It is a proposal, not a timed benchmark. Do not quote this script as a measured result.

#!/usr/bin/env bash
# receipt-check.sh - local check before share
set -euo pipefail

need() {
  test -s "$1" || exit 2
}

need prompt.txt
need claim-ledger.txt
need replay.txt

if rg -n -i 'api[_-]?key|secret|password|BEGIN ' prompt.txt; then
  printf '%s\n' 'redaction hit'
  exit 3
fi

if rg -n '^claim:.*bugfix' claim-ledger.txt >/dev/null; then
  if ! rg -n '^test:' claim-ledger.txt >/dev/null; then
    printf '%s\n' 'bugfix claim without test line'
    exit 4
  fi
fi

sha256sum prompt.txt claim-ledger.txt replay.txt > receipt.sha256
printf '%s\n' 'receipt ok'
Enter fullscreen mode Exit fullscreen mode

I invoke it from the worktree, not from memory. A bad exit means I stay local and fix the file. I do not negotiate with that exit code in chat.

bash receipt-check.sh
Enter fullscreen mode Exit fullscreen mode

Exit 2 means a required file is missing or empty. Exit 3 means the prompt search hit a secret-like string. Exit 4 means a bugfix claim has no test line.

I fix the file that failed, then I run the script again. I do not negotiate with the exit code in chat. A model apology is not an exit code.

How I read the exits

Exit Meaning Next move
0 Crude checks passed on the three files Read the diff once more, then share
2 A required file is missing or empty Write the file before any session
3 Prompt search hit a secret-like string Strip it and use a fake sample
4 Bugfix claim without a test line Add a test path or drop the claim

This table is a rule for my own branches. It is not a service level from any vendor. If your team needs signatures, this table is too small.

Where the free options fit

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

I mention MonkeyCode once, as one optional workbench. It offers free model access and a free server option. I do not name a model in this draft.

I do not state a token quota or a duration. An outreach note mentioned a free token pool. I will not repeat an unverified figure here.

No primary page was attached for me to check. Stale quotas are how teams plan the wrong week. Confirm the current docs yourself before you depend on them.

The workflow stays on my laptop until the receipt check passes. I write the prompt file, then I run the script. Only then do I ask a free model for a patch.

A free server can run the command stored in the replay file. I still commit the receipt next to the diff. The session log does not become the record.

If your team already hashes prompts, try this check on one branch. Tell me which table row feels too strict. That is the only ask I will make here.

Who should not use this

Do not use this script as a compliance archive. It has no signature, no clock sync, and no reviewer identity. A regulated repo needs a heavier trail than this.

Do not use the check to hide a diff you cannot read. The script checks that files exist and look non-empty. It does not understand your parser or your threat model.

Do not point the search at live production secrets. Use a fake sample when you test the pattern. I mean that as a hard stop, not a tip.

Skip the free server when the job needs private paths. Customer data and long-lived credentials stay off that box. Keep those runs on a machine you already trust.

The free option is for scratch work you can lose. If losing the run would hurt, do not start it there. A missing receipt is cheaper than a leaked trace.

Limits I am willing to say out loud

The search pattern misses secrets that look like normal words. The ledger can still be filled with confident lies. I can hash a bad prompt and still be wrong.

The check raises the cost of skipping a review step. It does not make me honest by itself. I still have to read the diff with my own eyes.

I did not execute these commands against a live product. Treat every block as a proposal until you run it. Verify current product terms before you plan a sprint.

Terms move, and my files should still make sense. That is the bar I am willing to keep. If the bar feels low, add a signature and keep the files.

Top comments (0)