Tellonce
English · 中文
Stop re-explaining yourself to your AI coding agent. Tellonce remembers the corrections you make and — when you ask it to — enforces them, so the same mistake doesn't come back. In our evaluations, held-out preference violations drop from 100% to 2.0% on out-of-distribution coding-agent tasks (research below).
You told your agent to stop writing scratch files to /tmp. To reply in your
language. To leave unrelated code alone. Three turns later it does it again.
Tellonce can scan turns for preferences, pitfalls, and workflow rules, record
them in a shared local store, and hard-enforce the ones you care about.
It is non-blocking and privacy-conservative by default: installation enables
local rule retrieval, but automatic model-backed memory upsert and hard
enforcement are both off. Enable memory upsert explicitly with
memory_upsert.py enable-hooks; it then sends a redacted copy of each complete
user turn to the current platform's CLI model in a detached worker. The separate
per-reply shadow judge also remains off until enabled.
✨ Highlights
- 🧠 Learns from your corrections when enabled. Automatic memory upsert is opt-in; local retrieval works without a model call.
- 🛡️ Opt-in enforcement. Turn it on and replies that violate your saved rules are blocked, and the agent fixes them in the same turn.
- 🔒 Local canonical storage. The SQLite memory remains on your machine.
Model-backed upsert and the optional shadow judge receive redacted text
through your own platform subscription. (Rule retrieval is fully
local by default — the
progressivebackend just reads your saved rule files, no model call; opt into small-model matching withPT_RETRIEVE_BACKEND=cli.) - ⚡ Runs on Claude Code, Codex, and GitHub Copilot CLI (one-command install on Copilot) — one shared memory across all three.
- 🎛️ Three modes, one switch:
observe→enforce→full.
📄 The research behind it
Tellonce is the deployable artifact of TRACE (Test-time Rule Acquisition and Compiled Enforcement) — our research on compiling user corrections into runtime enforcement for coding agents (arXiv:2606.13174). From the paper's simulated user-in-the-loop evaluations:
- Remembering ≠ honoring. With a state-of-the-art memory layer (Mem0), 57.5% of applicable preference checks were still violated on tasks derived from anonymized real-user friction cases. Memory recalls the correction; nothing makes the agent act on it.
- Compiled enforcement closes the gap. On coding-agent tasks (ClawArena), TRACE reduces held-out preference violation from 100% to 2.0% on out-of-distribution tasks, and from 100% to 37.6% in-distribution.
- Without giving up task quality. On memory-intensive tasks (MemoryArena-derived), TRACE cuts violations while matching or exceeding the strongest memory baseline on task pass rate.
And in real daily use, the correction rate behaves the way you'd hope: the author's own library grew to ~280 rules in its first two months of intensive use — then new-rule creation fell by 97% under continued daily work (single-digit new rules per month since), because the existing library already covers what used to need correcting. 88% of rules were right on the first write and never needed a revision.
Experiment code: YujunZhou/TRACE_exp · Cite: BibTeX
🚀 Quick start (Claude Code)
The native way — run these two commands inside Claude Code:
/plugin marketplace add YujunZhou/tellonce
/plugin install tellonce@tellonce
The hooks auto-register; start a new session to activate. Tellonce begins in the
safe observe mode (local retrieval, no automatic memory upsert, never blocks).
Enable background recording with python3 <plugin>/lib/memory_upsert.py enable-hooks; turn on hard blocking separately with export PT_ENFORCE=1.
git clone https://github.com/YujunZhou/tellonce.git ~/.claude/skills/tellonce
python3 ~/.claude/skills/tellonce/lib/_install_merge_settings.py --settings ~/.claude/settings.json --hooks-dir ~/.claude/skills/tellonce/hooks --add
That registers Tellonce user-global in ~/.claude/settings.json (every project
covered; state/memory still per-project). Per-project instead:
cd <project> && bash ~/.claude/skills/tellonce/install.sh. Full guide —
enforcement, uninstall — in INSTALL.md. Pick one method: if
you register via settings.json AND /plugin install, the hooks fire twice —
remove one (...--remove) before adding the other.
🚀 Quick start (Codex)
The native way — Codex CLI plugin marketplace (Codex CLI ≥ the March 2026 plugin release):
codex plugin marketplace add YujunZhou/tellonce
codex plugin add tellonce --marketplace tellonce
# verify: codex plugin list --marketplace tellonce -> installed, enabled
Tellonce begins in the safe audit_only mode (audits, never blocks); automatic
memory upsert remains off until explicitly enabled.
(The install verb is codex plugin add, not install.) The Codex marketplace
manifest is validated against the current Codex CLI (codex plugin marketplace add + the plugin validator pass); if /plugin install doesn't load the hooks on
your Codex build, use the manual install below.
git clone https://github.com/YujunZhou/tellonce.git ~/.codex/skills/tellonce
cd /path/to/your/project
bash ~/.codex/skills/tellonce/codex/install.sh # under codex/, NOT the repo-root install.sh
bash ~/.codex/skills/tellonce/codex/doctor.sh
See codex/docs/README.md for modes and the wrapper flow.
🚀 Quick start (GitHub Copilot CLI)
One-command bootstrap (recommended — pinned to the immutable tag v1.5.1, SHA256
published for pre-verification, see
copilot/README.md):
Windows (PowerShell)
powershell -ExecutionPolicy Bypass -Command "irm https://raw.githubusercontent.com/YujunZhou/tellonce/v1.5.1/copilot/bootstrap.ps1 | iex"
macOS / Linux
curl -fsSL https://raw.githubusercontent.com/YujunZhou/tellonce/v1.5.1/copilot/bootstrap.sh | bash
It downloads the Copilot-adapted plugin (the copilot/ sub-plugin — with
SessionStart injection, the Copilot Stop-block contract and Windows run.ps1
shims), copies it into Copilot's plugin directory, installs the optional
dependency, registers it, sets the safe observe mode, and records your Python
path. Restart Copilot when it's done.
⚠ Do not
copilot plugin install tellonce@telloncefrom this repo's marketplace — that entry is the Claude Code variant (repo root) and does not fit Copilot's hook surface (no per-prompt injection, different block contract,.claude/state paths). If you prefer a native plugin install of the sub-plugin, usecopilot plugin install YujunZhou/tellonce:copilot, then runbash <plugin_root>/install.shonce (seecopilot/README.md).
Supported platforms
| Platform | Status | Install | Docs |
|---|---|---|---|
| Claude Code | ✅ Recommended (largest user base) | /plugin install (above) |
docs/claude-code.md |
| Codex | Experimental | /plugin install (above) |
codex/docs/README.md |
| GitHub Copilot CLI | Supported (one-command install) | one command (above) | copilot/README.md |
All three share the same user-preference memory. Rule injection follows each
runtime's actual hook surface: Claude Code and Codex inject on
UserPromptSubmit; Copilot injects on SessionStart. Claude Code and Copilot
can inspect final responses with Stop; Codex uses native tool hooks and an
optional wrapper for final subprocess output. See
codex/docs/CC_PARITY_MATRIX.md.
Modes
| Mode | Hard block | LLM judge | What it does |
|---|---|---|---|
| observe (default) | off | off | Retrieves saved rules locally. Automatic memory upsert is controlled by a separate opt-in switch. |
| enforce | on | off | Deterministic hard-block layer plus the scan-completeness stop gate. The deterministic layer ships with no built-in rules (an opt-in extension point), so it blocks no content on its own; the stop gate self-seeds on first run. |
| full | on | on | enforce plus a small-model LLM judge that checks each reply against your recorded preferences (costs time / credit). |
Memory mutations use one SQLite transaction per complete user turn:
NOOP|UPDATE|SUPERSEDE|SPLIT|NEW|NEEDS_USER|REJECT|ARCHIVE|RESTORE. Each mutation
must cite short exact spans from that user turn; context cannot authorize a
rule. Unsafe durable rules are audited as REJECT rather than clarified or
installed. ARCHIVE removes an explicitly identified rule from retrieval while
preserving its SQLite version history; RESTORE reactivates it.
Switch at any time (Copilot variant):
python "<plugin>/lib/pt_mode.py" observe # back to the safe default
python "<plugin>/lib/pt_mode.py" enforce # turn on hard blocking
python "<plugin>/lib/pt_mode.py" full # hard blocking + LLM judge
python "<plugin>/lib/pt_mode.py" status # show the current mode
Privacy: canonical storage and progressive retrieval stay local.
When enabled, preference recording/merging calls the current platform's CLI
model with a redacted turn. An explicit manual --force enqueue can do the same
while automatic hooks are off. full additionally sends the redacted latest
message and reply to the CLI model for compliance scoring. For fully offline
use, leave memory upsert and the shadow judge disabled and keep progressive
retrieval.
How it works
- Rule injection — on Claude Code and Codex your saved rules are injected on every prompt (UserPromptSubmit); on Copilot once per session at SessionStart (its only injection point).
- Observation and memory upsert are separate — platform hooks may append a
local observation record, but no model-backed memory mutation runs unless
memory_upsert_enabledis explicitly enabled (or a manual forced enqueue is requested). - In
full— a small-model LLM judge checks each reply against the rules you list inPT_SHADOW_RULE_IDSand flags violations for the agent to fix. (Theenforcedeterministic layer ships with no built-in rules — it is an opt-in extension point, so it blocks no content by itself.)
Self-check & uninstall (Copilot variant)
python "<plugin>/lib/doctor.py" # self-check: python / registration / mode / hooks
python "<plugin>/lib/dashboard.py" # status at a glance: mode / rules / records
python "<plugin>/lib/uninstall.py" # dry-run: show what would be removed
python "<plugin>/lib/uninstall.py --all"
copilot plugin uninstall tellonce
<plugin> is printed at the end of install; it is
~/.copilot/installed-plugins/tellonce/tellonce.
Project layout
README.md # this landing page (English)
README.zh.md # Chinese companion
copilot/ # GitHub Copilot CLI variant — the public release
codex/ # Codex variant (wrapper-driven)
docs/claude-code.md # Claude Code variant, in depth
hooks/ lib/ SKILL.md ... # Claude Code variant (lives at the repo root)
seed_memory/ # empty by default; new users start with a blank slate
LICENSE
Citation
If you use Tellonce or build on TRACE in your research:
@article{zhou2026trace,
title = {Getting Better at Working With You: Compiling User Corrections
into Runtime Enforcement for Coding Agents},
author = {Zhou, Yujun and Guo, Kehan and Zhuang, Haomin and Wang, Xiangqi
and Huang, Yue and Liang, Zhenwen and Chen, Pin-Yu and Gao, Tian
and Moniz, Nuno and Chawla, Nitesh V. and Zhang, Xiangliang},
journal = {arXiv preprint arXiv:2606.13174},
year = {2026}
}
License
MIT — see LICENSE. An open-source research artifact for studying
in-session LLM preference enforcement. Issues and PRs welcome.
No comments yet
Be the first to share your take.