DEV Community

Haley
Haley

Posted on

Show the Withheld Context Before You Admit a Draft

Picture a Tuesday critique with six tired people. I am facilitating, and the clock is already rude. Someone pastes a generated empty-state line into the deck.

The line sounds kind, calm, and almost finished. Did anyone record what the model was allowed to read? I ask that, and the room goes quiet.

That quiet is the consent gap I refuse to skip. The decision owner is the critique facilitator, not the model. A false line could enter the shared component notes.

You can still throw the line away before anyone copies it. I treat this scene as a tutorial, not a field study. No metric here comes from a shipped product.

You can replay every step on your own laptop. Bring a public guideline, not a private transcript. If you cannot say the prompt aloud, you are not ready.

Name the decision before any prompt

Start with a paper decision, not a clever prompt. Who may admit this draft into critique today? What actually breaks if the line is wrong?

I write those answers before I open any generator. A missing owner stops the session before any prompt. A vague consequence is also a hard stop.

If you cannot name the undo point, wait. You are collecting hope, not a decision record. Hope is a poor ticket at the kitchen pass.

Create a folder and a ledger file first. Run the commands, then check that the file exists. This check is the first verification, not a formality.

mkdir -p critique-gate/fixtures
cd critique-gate
printf '%s\n' '{}' > fixtures/ledger.json
test -f fixtures/ledger.json && echo "ledger file exists"
Enter fullscreen mode Exit fullscreen mode

The echo line is your verification for this stage. If you do not see that message, stop here. A missing file is already a stop condition.

Keep evidence off the guess pile

Here is the analogy I use with design partners. A critique deck is a kitchen pass, not a junk drawer. The cook may plate a dish, but the expediter checks the ticket.

Evidence is something a person can point to. A hypothesis is what we hope the line will do. Those two must not share a field in the ledger.

That mix is the failure this protocol is built to catch. I keep the ledger shape below as a proposal. It is not a production schema for your company.

Change the words, but do not drop the refusal list. Save that object as fixtures/ledger.json on your disk. Then confirm that the refusal array is present.

{
  "decision_owner": "critique facilitator",
  "consequence": "empty-state line may enter component notes",
  "reversibility_point": "before notes are copied into the system",
  "allowed_context": ["public empty-state guideline"],
  "refused_context": ["support transcripts", "private user quotes"],
  "evidence": ["guideline says name the next action"],
  "hypotheses": ["shorter line may reduce abandonment"],
  "draft_text": "",
  "human_note": "",
  "admit": false
}
Enter fullscreen mode Exit fullscreen mode
node -e "const l=require('./fixtures/ledger.json'); if(!l.refused_context.length) process.exit(1); console.log('refusal list present')"
Enter fullscreen mode Exit fullscreen mode

You should see the words refusal list present. If the script exits with an error, stop. Why require a named refusal before any prose?

Silence about withheld context is not a boundary. It is just an empty chair at the table. Empty chairs do not protect anyone in the room.

Build a local gate with no network

Disclosure: This article was prepared as part of MonkeyCode's product outreach. The outreach brief describes MonkeyCode as an open-source project. It also describes free model access for practice drafts.

The same brief names a free server option. It states a free allotment of ten million tokens. I have not rechecked that number in a live console.

Confirm the current project page before you plan around it. I would use that access only to mint a disposable draft. I would not store the consent ledger on that server.

The ledger stays in the local folder you just made. If the free option vanishes, this gate should still run. A practice bench is not your system of record.

Would you bet a design-system note on a changing limit? The flow I want is short, and it stays local at the ends. Read it once before you write the checker.

public guideline
  -> local consent ledger
  -> gate prints hold or admit-ready
  -> optional public draft on a free bench
  -> human sets admit
  -> critique may still reject
refused context never enters the prompt
ledger never moves to the free server
Enter fullscreen mode Exit fullscreen mode

Write gate.js as a local checker with no network call. It only reads the ledger you pass on the command line. That limit is the whole point of the exercise.

const fs = require("fs");
const ledger = JSON.parse(fs.readFileSync(process.argv[2], "utf8"));
const missing = [];

function blank(value) {
  return value === undefined || String(value).trim() === "";
}

if (blank(ledger.decision_owner)) missing.push("decision_owner");
if (blank(ledger.consequence)) missing.push("consequence");
if (blank(ledger.reversibility_point)) missing.push("reversibility_point");
if (!Array.isArray(ledger.refused_context) || ledger.refused_context.length === 0) {
  missing.push("refused_context");
}
if (!Array.isArray(ledger.evidence) || ledger.evidence.length === 0) {
  missing.push("evidence");
}

const leaked = (ledger.evidence || []).filter((item) =>
  String(item).toLowerCase().includes("may ")
);
if (leaked.length) missing.push("evidence_looks_like_hypothesis");

if (missing.length) {
  console.error("hold", missing.join(","));
  process.exit(1);
}

console.log("admit-ready");
Enter fullscreen mode Exit fullscreen mode

Notice the script never sets admit for you. A complete record is not permission to ship. Check the syntax before you trust a green line.

node --check gate.js && echo "syntax ok"
Enter fullscreen mode Exit fullscreen mode

You should see the words syntax ok printed. If Node prints a parse error, fix the file. Do not paper over a syntax error with a manual note.

This script is a teaching example until you run it. It is not a judge of design quality or tone. It only checks whether a human recorded the boundary.

The may check is only a crude hint, not a parser. A real guideline might say users may retry. That phrase would trip this crude filter today.

Rename the hint or drop it before you rely on it. I would rather a false hold than a silent mix. You can delete that filter after the lesson lands.

Fail the gate on purpose

Copy the ledger and strip the refusal list. Then run the gate and welcome the failure. A green light here would mean the gate is fake.

node -e "const l=require('./fixtures/ledger.json'); delete l.refused_context; require('fs').writeFileSync('fixtures/bad.json', JSON.stringify(l, null, 2));"
node gate.js fixtures/bad.json; echo "exit:$?"
Enter fullscreen mode Exit fullscreen mode

I expect a hold message and an exit code of 1. If you see admit-ready, fix the script before you trust it. A gate that smiles at a missing refusal is theater.

Now run the same command against the good file. Keep admit false until a human reads the line. The script does not need that flag to judge completeness.

node gate.js fixtures/ledger.json; echo "exit:$?"
Enter fullscreen mode Exit fullscreen mode

You should see admit-ready and an exit code of 0. That result means the record is complete enough to discuss. It does not mean the sentence is good, kind, or true.

Ask for one public line

Only now do I ask a model for draft text. I paste the allowed context, never the refused context. I ask for one empty-state line and a non-use note.

If you try the free model access, keep the prompt public. Do not paste transcripts, tokens, or private user quotes. A free server is still a server someone else operates.

Would you read that prompt aloud in the critique? If the answer is no, the prompt is already too private. Shrink it until the answer becomes a bored yes.

When a draft returns, paste it into draft_text by hand. Do not let the generator edit the admit field. The human flips that field only after reading the card.

Rerun the gate after you save the hand edit. Exit code 0 means the record is ready for discussion. Critique can still reject the words without apology.

Put that rejection in human_note on the same file. Discarded wording should stay beside the refusal list. If you delete the loser, the next critique repeats the quiet.

node -e "const p='fixtures/ledger.json'; const l=require('./'+p); if(!l.draft_text){console.error('draft missing'); process.exit(1)} if(l.admit!==false){console.error('admit flipped too early'); process.exit(1)} console.log('draft parked, admit still false')"
Enter fullscreen mode Exit fullscreen mode

You should see draft parked, admit still false. If admit is already true, a tool jumped the human. Put that flag back before the critique starts.

Read the card before the shiny line

The gate output is ugly on purpose, and that is fine. A critique still needs a card a person can read aloud. I speak the pattern instead of hiding status in color.

The card title is the decision, not the draft. The first line names the owner in plain text. The next line names the consequence in the same voice.

Then I read the refusal list before the draft text. Why that order, when the sentence looks finished? Because the shiny line will steal the room.

A screen reader user should reach Refuse without a mouse. The refuse control needs a visible name, not an icon alone. Status must not depend on red or green alone.

I write the hold reason as a full sentence. We did not record what the model must not read. Consent gap may confuse a new teammate in the room.

Keep both the short label and the slower sentence. If the card truncates the refusal list, call it a failure. Hidden withheld context is the same quiet we started with.

Would you approve a ticket you cannot fully scroll? I would not, and I would send the card back. Another person should name the refusal without your help.

That spoken check is the verification for this stage. If they cannot name it, the card failed. Fix the card before you discuss the sentence.

Rehearse three scenes, then stop

I rehearse three scenes before I trust the habit. Scene one uses only a public empty-state guideline. The gate should print admit-ready for that scene.

Scene two omits the owner and keeps everything else. The gate should hold, and the session should stop. No draft is worth an unnamed decision owner.

Scene three puts a private quote in allowed context. I stop by policy even if the script stays green. The checker does not understand privacy, but you do.

Add a human scan for names, tickets, and raw quotes. Do that scan before you set admit to true. A green script cannot see a name you forgot to hide.

Success here is modest, and I want it that way. A facilitator can name the owner, the harm, and the undo. A missing refusal list blocks admission every time.

A hypothesis never sits inside the evidence array. Stop the method if nobody will own the decision. Stop if the draft touches health, finance, or account data.

Stop if your team treats exit code 0 as taste approval. This checker cannot see a bad or biased sentence. It cannot score the accessibility of the product screen.

Pair the gate with a separate read of the real interface. The protocol does not replace that interface read. It only stops a draft from entering critique naked.

What the exit codes do not prove

I am not claiming a usability study or a benchmark. I have no completion rate and no customer quote. Please do not cite this article as either one.

The recommendation rests on a failure you can reproduce. The supporting evidence is the exit codes you just watched. The critique scene is a teaching frame, not a dataset.

One design hypothesis sits beside that evidence. A visible consent ledger may reduce silent pastes into critique. Test that with your own team before you write a rule.

Five facilitated sessions would be a humble start. A hallway opinion is not evidence for a system rule. Label that hypothesis until those sessions actually exist.

Do not use this flow for production audit logs. Do not use it as a legal record of consent. Do not use it where counsel expects a retention proof.

Skip it if you need named models, latency, or a permanent quota. Those facts change, and this draft does not certify them. Who else should leave this method on the shelf?

Skip it when your prompt cannot be read aloud. Skip it when you need a private region or a retention note. The brief's free access is a practice bench, not a vault.

People who want the model to approve its own copy should walk away. Teams without a named facilitator should walk away too. The gate will not invent an owner for you.

If a disposable bench would help, read the current MonkeyCode notes. Try the free model access on public text only. Keep the ledger on your machine either way.

Top comments (2)

Collapse
 
alexshev profile image
Alex Shev •

The explicit refusal list is a strong guard because it turns omitted context into something reviewers can inspect instead of an assumption. It could be even easier to audit if each admitted draft carried a compact context manifest with allowed sources, withheld categories, decision owner, and the reversal point next to the text it authorized.

Collapse
 
suppdevbot profile image
DEV SUPPORTS •
You need to verify your account.
Enter fullscreen mode Exit fullscreen mode

tr.ee/dev-to