agentsclimarketplace

Tellonce

Skill YujunZhou/tellonce/codex/skills/tellonce

In-session compliance enforcement skill for Claude Code (paper Sec 6 dogfood). Per-user adaptive threshold + chaos-tested install/doctor/uninstall.

Install
npx -y skills add YujunZhou/tellonce --skill tellonce

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 5 stars5 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Use when handling any user message; records and enforces user preferences with Codex-native audit/wrapper support.

SKILL.md

9.5 KB, as published. Nobody here has run it

Tellonce for Codex

Codex actually exposes the same hook system as Claude Code (PreToolUse / PostToolUse / SessionStart / UserPromptSubmit / PermissionRequest). The codex variant of tellonce installs into ~/.codex/skills/tellonce/

  • ~/.codex/hooks.json and uses native hooks for retrieval + enforcement. The wrapper path (tellonce_codex exec --) is still the way to enforce on the FINAL agent text response (codex doesn't fire a Stop hook for that; PostToolUse only sees tool inputs/outputs).

Core rules (every turn)

  • Scan every user message for preference, pitfall, friction, or none.
  • Apply known preferences before responding (read <state>/index/active_memories.json).
  • Record durable evidence through tellonce_codex scan when installed.
  • Wrap any subprocess that produces user-facing output via tellonce_codex exec -- <cmd> so its stdout is verified and audited.

Rule injection (progressive full index — default)

Each time the user submits a message, userpromptsubmit-retrieve-inject.sh injects a one-line index of the rules saved under the project memory dir as additionalContext, and I judge which apply. If the library exceeds the per-turn cap (default 50 — progressive_max in ~/.tellonce.config.json or PT_PROGRESSIVE_MAX, 0 = no cap), tier-1 rules are pinned when they fit under the cap (when tier-1 alone overflows it, the whole library rotates instead), the remaining rules rotate in across turns, and the block states how many of the total are shown. This is the default progressive backend: it just reads the saved rule files — no prompt matching, no model call, no CLI cold-start. The format looks like this — it's not external noise, it's a rule hint from the skill infra and must be respected:

### Your saved preferences — check each against this turn and apply the ones that fit:
- [fmt-pref-001] (tier1) use 4 spaces for indentation, not tabs
- [tool-pref-002] (tier2) prefer the project's own package manager / lockfile for installing dependencies | when: adding / upgrading dependencies
(These are your recorded preferences. Judge each rule against the current task; apply those that apply, skip those that do not.)

Each line carries the rule's rule_text/description and (when present) a when: applicability hint. I judge for myself whether it holds for the current turn, and skip rules that don't apply.

Legacy backends (PT_RETRIEVE_BACKEND=cli / keyword / api) instead inject only the rules matched for the current prompt, under a ### Fingerprint retrieval — ... header. The judgement I apply is the same.

audit_only  ──first wrapper run──▶  wrapper  ──opt-in──▶  blocking
  • audit_only: scan + record + advisory stderr; PostToolUse hook never blocks. Default after install.
  • wrapper: at least one tellonce_codex exec run has completed; same advisory behavior as audit_only.
  • blocking: PostToolUse hook returns exit 2 + decision:block JSON when violations detected. Opt-in only — set by editing <state_root>/mode.json (write_mode enforces monotonicity: never downgrade).

The state lives in <state_root>/mode.json. register_project only writes the default mode on first install; later CLI invocations preserve any wrapper-mode upgrade.

When to call which command

You want to ...Run
Bootstrap state for this projecttellonce_codex install --project-root .
Record a scan event for the latest user messagetellonce_codex scan --project-root . --message "..."
Audit a subprocess's stdout (the main wrapper path)tellonce_codex exec --project-root . -- <cmd...>
Promote a candidate to durable memory (programmatic)call tellonce_codex.promote.promote_candidate(state, candidate) directly
Health check + leak audittellonce_codex doctor --project-root .
Summarytellonce_codex dashboard --project-root .
Uninstall integration (keep data)tellonce_codex uninstall --project-root .
Uninstall + delete all statetellonce_codex uninstall --project-root . --purge-state

-- is required for exec

tellonce_codex exec --project-root /path -- claude -p "do thing"
#                    ^^^^^^^^^^^^^^^^^^^   ^^
#                    tellonce_codex flags  separator     wrapped command

Without --, argparse may swallow flags meant for the wrapped binary. The CLI prints an explicit error if -- is missing.

Timeout

tellonce_codex exec defaults to 600s. Override with --timeout 1200 or CODEX_PT_TIMEOUT=1200 env. Long LLM sessions need this — the prior 120s default cut every real session.

Whitelist for inline-English check

Codex's verify_output flags inline English tokens in mostly-Chinese responses (rule lang-pit-130). Both built-in verify rules are env-gated OFF by default — enable with CODEX_PT_LANG_RULE=1 (inline-English) and CODEX_PT_TMP_RULE=1 (/tmp paths); without those flags the wrapper only audits/redacts. To avoid false positives once enabled:

  • A small base whitelist (programming terms like api, json, http, model names like claude, gpt) is built in.
  • Add project-specific tokens to <state_root>/whitelist.txt (one per line, # for comments).
  • Or set CODEX_PT_WHITELIST=/path/to/file for a global file.

Doctor states (what's normal)

doctor.run_doctor() returns wrapper={PASS, NOT_USED}. NOT_USED is normal on a fresh install — it just means no tellonce_codex exec has run yet. It's not an error.

Privacy

  • Subprocess stdout/stderr go through sanitize() before disk (redacts API keys, DB URIs, JWT, SSH private-key blocks, etc.).
  • Files under <state_root> are written with mode 0o600 (user-only), and <state_root> itself is 0o700.
  • The wrapped subprocess gets a filtered env: anything matching *TOKEN* / *SECRET* / *PASSWORD* / *API_KEY* / *AUTH* etc. is dropped before the subprocess starts, except an explicit allowlist of standard LLM/dev-tool credentials (ANTHROPIC_API_KEY, OPENAI_API_KEY, GH_TOKEN, ... — see wrapper._ENV_ALLOW_NAMES) that the wrapped CLIs need to function. CODEX_PT_STRICT_ENV=1 disables that allowlist for a pure deny-list.
  • See tellonce_codex.ledger.SECRET_PATTERNS for the redaction patterns; extend via PR if your stack has a key prefix not yet covered.

Setup

# From the project root. Installs:
#   1. global runtime — tellonce_codex/ + shared_lib/ (CC lib copy)
#      + hooks/ + seed_memory/ (reference rule examples only — nothing
#      auto-loads them) + SKILL.md. Default target is
#      ~/.codex/skills/tellonce/; if your git clone occupies that
#      path, the runtime goes to ~/.codex/skills/tellonce-runtime/
#      (keeps the clone clean).
#   2. ~/.codex/hooks.json — registers UserPromptSubmit (3) + PostToolUse + SessionStart
#   3. <project>/.codex/tellonce/ — per-project state (audit_only mode by default)
bash <repo>/codex/install.sh    # the repo-root install.sh is the Claude Code variant

# Verify (state + hooks status + private-path leak scan) — easiest:
bash <repo>/codex/doctor.sh
# or module form (point PYTHONPATH at wherever the runtime landed):
PYTHONPATH=~/.codex/skills/tellonce-runtime python3 -m tellonce_codex doctor  # clone layout
PYTHONPATH=~/.codex/skills/tellonce python3 -m tellonce_codex doctor          # plain layout

One-time hook trust approval (required — hooks are silently skipped until then)

Codex trusts hooks by a hash of their exact definition. Newly installed or changed hooks do not run — no error, no log, they are simply skipped — until you review and approve them once in an interactive Codex session (Codex prompts on the next session start; accept the tellonce entries). This applies after first install AND after any upgrade that touches hooks.json (including re-running install.sh, whose remove-then-add re-orders the definitions). If hooks seem dead ("installed but nothing happens"), a missing trust approval is the first thing to check. One-off verification without trust: codex exec --dangerously-bypass-hook-trust ....

Hook flow

Hook eventScriptPurpose
UserPromptSubmituserpromptsubmit-retrieve-inject.shinject a one-line index of the saved rules (default progressive backend; legacy backends match the prompt via fingerprints/CLI/API instead) as additionalContext
UserPromptSubmituserpromptsubmit-pending-inject.shwarn about pending memory entries from prior session crashes
UserPromptSubmituserpromptsubmit-shadow-alert-inject.shinject "last turn violated rule X" reminder so this turn fixes it
PostToolUseposttooluse-deterministic-block.shregex/fingerprint scan agent's tool input (Write content / Edit / Bash); audit_only logs, blocking mode exits 2 + decision:block
SessionStartsessionstart-init.shlazy-init project state on first codex SessionStart in a fresh project

Mode state machine

The three modes are rank-ordered (_MODE_RANK in tellonce_codex/mode.py): audit_only (0) → wrapper (1) → blocking (2). Per project, the persisted mode only latches upward — write_mode raises ModeDowngradeError on any silent downgrade (allow_downgrade=True exists for test fixtures only). blocking is opt-in only; nothing auto-promotes into it. wrapper_seen latches True the first time tellonce_codex exec is used and never resets, so doctor/dashboard can tell whether wrapper enforcement has ever run here.

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.