readback-gate
v0.1.0
Published
Coding agents read back what they understood, before they act on it. A runtime prompt gate for AI coding agents.
Maintainers
Readme
readback-gate
Your coding agent reads back what it understood — before it acts on it.
English · 한국어
A runtime prompt gate for AI coding agents. It catches ambiguous tasks the moment you hit enter — inside the loop, before the agent misreads them and edits the wrong thing.
The problem
You type "just clean this up and handle it." The agent confidently does the wrong thing — and you find out three file edits later.
Other tools check your prompt in a browser, or lint your config files. None of them catch the command you just typed, in the loop, before it runs.
What it does
Before — an ambiguous prompt:
just clean everything up and handle itreadback-gate scores it as low-clarity and injects a short instruction into the agent's context:
Readback-gate: clarity_score=16, risk_level=none, missing=goal_clarity, target_context, context_dependency, done_condition.
If the prompt is ambiguous, do not execute yet. First sync intent in this format:
1. State the understood goal in one sentence.
2. List 2-4 plausible interpretations as options.
3. Recommend one with a short reason.
4. Ask exactly one clarification question, then stop.After — a clear prompt passes untouched:
Add a risk_level test to src/core/scorer.ts and verify with npm testIt has a target, bounded scope, and a verification command — so it passes.
Why it's different
| | What it checks | When | Blocks? | |---|---|---|---| | Browser paste tools | prompt text | outside the loop | report only | | Config linters | static config files | commit / CI | file fix | | readback-gate | the prompt you just typed | in the loop, pre-execution | inject (default) / opt-in block |
- Deterministic & local. The scoring path never calls an LLM or the network — same prompt, same score, every time.
- Inject, don't block. Blocking your own command is paternalistic; injecting "read back first" is not. Hard blocking is opt-in (
strict). - Non-execution aware. Questions, acknowledgements, and read-only queries pass through untouched.
Install
Status: pre-release (v0). Install from source. An
npx readback-gatepackage is on the roadmap (see Roadmap).
Requires Node ≥ 24 (uses native TypeScript execution).
git clone https://github.com/dkwlsdl3/readback-gate
cd readback-gate
npm install -g . # installs `readback-gate` and `readback-gate-codex`Usage
CLI
readback-gate "just clean everything up and handle it"Prints a human summary plus a report JSON:
{
"version": "0.1.0",
"clarity_score": 16,
"risk_level": "none",
"verdict": "inject",
"axes": {
"goal_clarity": 84,
"target_context": 68,
"scope_boundedness": 88,
"done_condition": 90,
"risk_side_effect": 100,
"context_dependency": 88
},
"missing": ["goal_clarity", "target_context", "context_dependency", "done_condition"],
"trigger_reasons": ["The requested action is vague or delegation-heavy."],
"suggested_questions": ["What exact outcome should the agent produce?"]
}As a hook (Codex / Claude Code)
Both agents speak the same UserPromptSubmit protocol, so the same adapter
works for both. Register readback-gate-codex as a UserPromptSubmit hook —
see install/README.md for the exact entries. The adapter:
- emits
{"hookSpecificOutput":{...,"additionalContext":"..."}}to inject, or - emits
{}to pass through, or - in
strictmode, prints a reason to stderr and exits2to block.
Modes
| Mode | Behavior |
|---|---|
| silent | Injects one score/missing-signal line. No instruction. |
| inject (default) | Injects score/signals + the 4-step readback instruction. |
| advisory | Prints a report to stderr and continues. |
| strict | Blocks (exit 2) only when clarity_score < threshold and risk_level == high; otherwise behaves like inject. |
Configure via env: READBACK_GATE_MODE, READBACK_GATE_THRESHOLD (default 70),
READBACK_GATE_TELEMETRY.
How scoring works
clarity_score (0–100) is 100 minus deterministic penalties across six axes.
A separate risk_level (none/low/medium/high) drives strict gating.
| Axis | Penalized when… | |---|---| | goal clarity | vague verb (handle / sort out), or no action verb | | target/context | no concrete file, path, symbol, or module | | scope boundedness | unbounded scope (all / everything / entire) | | done condition | no verifiable completion signal | | risk / side-effect | destructive/remote/prod action with no acknowledgement | | context dependency | relies on unresolved references or prior turns |
Both English and Korean are detected. See docs/spec-v0.md for the full model and §13 for known limitations.
Privacy
- Raw prompts are never stored. Only
prompt_hash, length, score, risk, verdict, and missing axes are recorded. - Telemetry is local JSONL only — no remote transmission.
Roadmap
- [ ] JS build step +
npm publish→npx readback-gate - [ ] Dedicated Claude Code adapter (the boundary is already clean)
- [ ] Validity analysis: does low clarity correlate with rework?
- [ ] Tighten the mutating-verb denylist (§13)
Development
No runtime dependencies.
npm test
readback-gate "Add a test to src/core/scorer.ts and run npm test"
READBACK_GATE_MODE=strict node src/adapters/codex.ts < test/fixtures/codex-ambiguous.jsonLicense
MIT
