npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@lannguyensi/understanding-gate

v0.7.1

Published

Pre-execution gate that asks AI agents to produce an Understanding Report before acting

Readme

understanding-gate

Pre-execution gate for AI agent harnesses.

Overview

Before an agent edits files, runs destructive commands, or opens PRs, this tool asks it to emit a structured Understanding Report so a human can confirm, correct, or "grill me" before execution begins.

Status: Phase 2 (enforcement) shipped. Phases -1, 0, 0.5, 1, 2 are live: prompt-hook gate, structured report parsing + persistence, and tool-blocking until the report is approved. Phase 3 (agent-tasks lifecycle integration) is next. See ROADMAP.md.

The gate sits in front of your agent harness as two layers, intentionally separated so each does one job well:

Layer 1, the cooperative gate (Phase 0). A UserPromptSubmit hook injects an instruction into every task-like prompt asking the agent to first produce a report covering: current understanding, intended outcome, derived todos, acceptance criteria, assumptions, open questions, out-of-scope, risks, verification plan, prior art (what was searched for an existing solution, the closest match found, and an adopt / extend / build-new judgment). A cooperative agent reads this and pauses for human confirmation. This is where most of the value comes from in practice: the agent slows down on its own and surfaces its interpretation before doing anything irreversible.

Layer 2, the enforced backstop (Phase 2). A PreToolUse hook blocks destructive tools (Write, Edit, MultiEdit, NotebookEdit, Bash on Claude Code; write, edit, bash on opencode) until the latest persisted Understanding Report for the active task has approvalStatus: "approved". Read-only tools (Read, Grep, Glob, LS, ...) stay open at all times. Every block, approve, revoke, and force-bypass lands in .understanding-gate/audit.log. This is what fires when an agent ignores Layer 1, whether because of an aggressive prompt ("don't ask, just do"), a prompt-injection attack, or a less-cooperative model.

Key features

  • Two modes for the cooperative layer: fast_confirm (default, 5-line summary) and grill_me (10-section report)
  • Enforced backstop that blocks write/execute tools until a report is approved, with an audited force-bypass and an optional pause sentinel
  • One-shot installers for Claude Code and opencode hooks
  • Every block, approve, revoke, and force-bypass decision is JSONL-audited

Agentic systems often fail at the transition from partially-understood task to real-world action: the agent infers too much too early, executes on wrong assumptions, and the result is off-target. A pre-execution gate makes the interpretation visible and reviewable before the first impactful action. This is the front-of-pipeline counterpart to claim-gate (no claims without evidence) and review-claim-gate (no merge without checklist). Same family, earlier checkpoint.

Install / quick start

Claude Code

npx @lannguyensi/understanding-gate init --target claude-code

Writes three hook entries into .claude/settings.json (project scope) or ~/.claude/settings.json (--scope user): UserPromptSubmit (Layer-1 prompt template, Phase 0), Stop (parses the agent's final message and persists the report, Phase 1), and PreToolUse (Layer-2 enforcement, Phase 2). All three are installed in one shot. The UserPromptSubmit hook only fires on task-like prompts (keyword classifier), so non-task questions are unaffected. To remove the entries again, run understanding-gate uninstall --target claude-code (respects the same --scope).

opencode (v0.5)

npx @lannguyensi/understanding-gate init --target opencode

opencode has no per-prompt hook before model inference, so v0.5 installs three files: .opencode/rules/understanding-gate.md (the static fast-confirm rule the agent always sees), .opencode/command/grill.md (the explicit /grill command), and .opencode/plugins/understanding-gate-persist-report.ts (a message.updated plugin shim that parses the agent's report and writes it to .understanding-gate/reports/; without this shim Phases 1 and 2 degrade silently). --scope user installs the three files under ~/.config/opencode/ instead of .opencode/. To remove the three files again, run understanding-gate uninstall --target opencode. See opencode integration notes for testing the plugin's failure path.

Non-interactive sessions (claude -p)

Phase 2 works under claude -p as long as the harness ships last_assistant_message in the Stop-hook payload (recent Claude Code releases do). For older harnesses the gate falls back to reading the transcript JSONL, which can race against the harness's flush timing. If .understanding-gate/reports/ stays empty under a -p run while the agent's output clearly contains a # Understanding Report, that race is the most likely cause; upgrade the harness or run interactively as a workaround.

Usage

Modes

| Mode | When | Shape | |---|---|---| | fast_confirm (default) | low-risk, small tasks | 5-line summary, "please confirm" | | grill_me | ambiguous, risky, broad | 10-section report, "please grill me" |

Escalation to grill_me: set UNDERSTANDING_GATE_MODE=grill_me, or include grill me / /grill in the prompt. On Claude Code both modes are persisted: the Stop hook maps the five fast_confirm bullets onto report sections and validates them against a relaxed schema, so a fast_confirm report can be approved like a grill_me report. On opencode, the persist-report plugin only picks up replies that contain an Understanding Report heading line, so use /grill there when Layer 2 needs a report to approve.

Approve / revoke the gate

# After the agent emits a report you accept, in another terminal:
understanding-gate approve            # the latest report, when all reports share one taskId
understanding-gate approve --task-id <id>
understanding-gate approve --report-id <taskId|filename|path>

# Reverse it:
understanding-gate revoke

# Inspect:
understanding-gate status              # current approval state in cwd
understanding-gate report list         # all persisted reports
understanding-gate report show <id>    # one report (taskId, filename, or path)

The CLI flips the persisted report's approvalStatus field, which is the source of truth the PreToolUse hook reads. Each approve / revoke also drops a JSONL line in .understanding-gate/audit.log (block, approve, revoke, force_bypass, paused_allow, degraded_allow).

approve, revoke, status, report list and report show accept --dir <path> to read reports from another directory. --dir overrides UNDERSTANDING_GATE_REPORT_DIR, which overrides the default .understanding-gate/reports/. revoke takes the same --task-id / --report-id selectors as approve. report list --json prints JSON instead of a table, and status --task-id <id> limits the output to one taskId.

Debugging: understanding-gate print --mode fast_confirm|grill_me prints the snippet the UserPromptSubmit hook injects; --mode full prints the standalone full template, which no hook injects.

Files and state

| Path | Contents | |---|---| | .understanding-gate/reports/ | Persisted reports; moved by UNDERSTANDING_GATE_REPORT_DIR | | .understanding-gate/audit.log | JSONL audit, always under the working directory | | parse-errors/, sync-errors/ | Breadcrumbs for failed parses and failed hypothesis syncs, next to the reports dir | | hypotheses.json | Assumptions and open questions registered as hypothesis-tracker entries, next to the reports dir |

The PreToolUse hook checks the latest report for the active task id (UNDERSTANDING_GATE_TASK_ID, else the harness session id), so approving a report for another task id does not unblock this one (sessions that share UNDERSTANDING_GATE_TASK_ID share approval). approve without flags works only when every report shares one taskId; otherwise pass --task-id.

Disable or force-bypass

# Kill switch (gate is off and writes no audit entry of its own; the
# PreToolUse hook still audits a payload that is empty, not a JSON object,
# or has no tool_name as degraded_allow):
UNDERSTANDING_GATE_DISABLE=1 claude

# Bypass enforcement once with a recorded reason (>= 10 chars; logged):
UNDERSTANDING_GATE_FORCE=1 \
UNDERSTANDING_GATE_FORCE_REASON="incident-recovery for ticket 1234" \
claude

FORCE without a FORCE_REASON (or with one shorter than 10 chars) still blocks; the bypass is deliberately friction-bearing.

Documentation

Not implemented yet

Phases -1, 0, 0.5, 1, 2 are live. The following items are deliberately out of scope for the current release; some are scheduled for later phases, some are deferred indefinitely:

  • Call an LLM for prompt classification. The task-like classifier is a deterministic keyword regex. Determinism plus zero per-prompt latency.
  • Sync approval state to agent-tasks. Phase 3 promotes the local marker to a first-class lifecycle state.
  • Auto-escalate to grill_me based on risk heuristics. Manual escalation only for now.
  • Time-based expiry of approvals. An approved report stays approved until you revoke.

Development

npm install
npm run build
npm test

License

MIT, experimental / pre-release. APIs may change between phases.