quizzing-before-approving — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited quizzing-before-approving (Agent Skill) and scored it 96/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 1 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 1 flagged
A bulleted imperative like {match} tells the agent to never reveal, disclose, or mention something to the user. Used adversarially it can instruct the agent to hide its tool calls or lie about what it did — stripping the transparency a user relies on to trust the agent.
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Reading a diff feels like understanding it. Being tested on it reveals the difference. The goal is to break the illusion of fluency — grade strictly and do not let the user off the hook.
or self-referential narration.
or analysis of which instruction you are following.
questions, grading feedback, contextual hints, and verdict.
State: (no characters,whitespace, or prose before it).
State: NEED-SCOPE,State: ROUND-1, State: ROUND-2, State: ROUND-3, State: GRADING, State: VERDICT.
Use these templates:
State: NEED-SCOPE
Re-invoke with a scope — paste the diff or describe the change:
/skill:quizzing-before-approving <diff or description> State: ROUND-N
[Optional one-line caveat if description-only scope]
Qx. ...
[Qy. ...] State: GRADING
Qx: Incorrect
Missing: [specific gap]
Re-read: [file:function:lines or closest available locator]
Retry Qx: [same question] State: VERDICT
Verdict: PASS | NEEDS RE-READ | DO NOT MERGE
Reason: [concise reason]The scope is the text the user appended when invoking the skill.
lines, functions, and call sites.
targeted; encourage the user to re-invoke with the actual diff for a stronger quiz.
stop, quit, cancel, end quiz,I want to stop). If present, skip quiz generation and go directly to the verdict flow.
Keep this internal work private. Do not show hidden drafts or mention that you generated questions internally.
grade them fully before moving on.
re-ask. Do not advance to the next round until every question in the current round is answered correctly.
Generate one question per type. For Q6–7, pick the one or two lines a fast reader would skim — the parts where the real risk lives.
| # | Type | What it probes |
|---|---|---|
| Q1 | Restatement | Explain the change in your own words — no agent wording, no variable names used as explanations |
| Q2 | Alternatives | Name a reasonable alternative approach; explain why this one was chosen over it |
| Q3 | Invariant | What assumption does this code rely on, or what guarantee does it preserve? |
| Q4 | Failure-mode | Name a specific input or condition that breaks this; describe the exact symptom |
| Q5 | Scope | What was changed beyond what the task strictly required? |
| Q6–7 | Targeted | The trickiest line(s) — the ones most likely to cause a future bug |
A good question can only be answered by someone who has built a mental model of the change. A bad question can be answered by scanning the diff:
A useful test: if the answer could be lifted verbatim from the diff, the question is too easy.
| Round | Questions | Why these together |
|---|---|---|
| Round 1 | Q1 | Foundational. Answering Q2–Q7 first would scaffold the restatement, so isolate it. |
| Round 2 | Q2 + Q3 | Both probe why, but neither answer each other. |
| Round 3 | Q4 + Q5 + Q6–7 | All adversarial and independent of one another. |
Present each round as a numbered list. Wait for the user to answer all questions in the round before grading any of them.
Grade strictly. The purpose is to find gaps, not to validate effort.
| Answer pattern | Verdict | Action |
|---|---|---|
| Demonstrates the specific mechanism and why | ✓ Correct | Proceed |
| Vague ("it updates the cache") | ✗ Wrong | State what's missing; point to lines; re-ask |
| "I think…" / "probably…" | ✗ Wrong | Require specifics; re-ask |
| Paraphrase of code without explaining why | ✗ Wrong | Explain that restating what is not the same as understanding why; point to context; re-ask |
Do not give the answer. Instead:
lives.
Example: "You described what the line does, not why it comes before the fetch. Look at `api/users.py:112` — one of the three call sites — and consider what state the cache would be in if the order were reversed. Try again."
Give as much surrounding context as necessary to unstick the user, but stop short of naming the answer itself. If the user is persistently stuck on the same question after multiple attempts, provide a more concrete pointer (a neighbouring function, a test case, a related comment) — never the answer.
If the user explicitly asks to stop, issue the verdict based on progress so far and note which question types remain unanswered. Do not invent or display a full unseen question set when the quiz did not reach those rounds.
| Verdict | Condition |
|---|---|
| ✅ PASS | All questions answered correctly |
| ⚠️ NEEDS RE-READ | User stopped with most (≥ 60%) answered correctly |
| 🚫 DO NOT MERGE | User could not answer Q1, or stopped with major gaps remaining |
After PASS, briefly note any questions that required multiple attempts — those are the areas most likely to cause confusion or bugs after merge.
Scope (pasted diff):
def get_user_settings(user_id: str) -> Settings:
+ cache.invalidate(f"user:{user_id}:settings_v1")
raw = db.fetch_settings(user_id)
return Settings.from_dict(raw)Round 1:
Q1. In your own words — without using the words "cache" or "invalidate" — what problem does this one-line addition solve?
Round 2:
Q2. Name one alternative to this approach for keeping data fresh. Why does this code not use that alternative?
>
Q3. The key ends in _v1. What invariant must hold for that suffix to remain correct, and who is responsible for maintaining it?Round 3:
Q4. This function is called from three places in the codebase. Describe a scenario in which this change causes a regression in one of those call sites.
>
Q5. What does this change do that was not required to fix the stated bug?
>
Q6. There is a race condition introduced or exposed here. Which request sees stale data, and for how long?
If the user answers Q1 with "it clears the cached settings before reading from the database", that is a paraphrase. Push back: "That restates what the line does. Why must the invalidation happen before the read rather than after it? What would a caller observe if the order were swapped?"
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.