writing-anki-cards — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited writing-anki-cards (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
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.
This skill is add-only: generate cards and insert notes into Anki. Do not run review/update/delete workflows.
SKILL_DIR="$(dirname "$SKILL_PATH")"
PIPELINE="$SKILL_DIR/scripts/anki_add_pipeline.py"
REFS="$SKILL_DIR/references"/tmp/source.txt and run the source gate.python3, jqpyyaml: python3 -m venv .venv && source .venv/bin/activate && pip install pyyamlpi CLI (for the per-chunk evaluator)1. Save source material to /tmp/source.txt.
2. Run source gate — always, regardless of source size. Produces a chunk plan and source metrics YAML before any cards are written. See Source gate below.
3. Read card formulation principles using the read tool — mandatory before writing any cards:
read "$REFS/01-card-formulation-principles.md"read "$REFS/02-advanced-techniques.md"4. For each chunk — manually generate → evaluate every card once → rewrite → move on:
a. Manually formulate cards from that chunk's source sections → write /tmp/anki-chunk-N.yaml. Do not mechanically derive cards with scripts, regexes, heading/table extraction, sentence clozing, or template expansion. Card prompts and answers must come from deliberate card-design judgment. b. Run the per-chunk evaluator on /tmp/anki-chunk-N.yaml → read the full free-form output, including the card-by-card verdict for every card. See Per-chunk evaluator below. c. Rewrite `/tmp/anki-chunk-N.yaml` completely based on evaluation output. Do not make surgical edits — the evaluator may identify structural issues (missing coverage, ratio drift, systematic patterns) that require adding or removing cards, not just editing existing ones. d. Confirm every card remaining in /tmp/anki-chunk-N.yaml has either an evaluator OK verdict or was rewritten in response to evaluator feedback. The post-rewrite chunk does not need a second evaluator pass. If any card was neither reviewed by the evaluator nor rewritten in response to evaluator feedback, do not merge or add that chunk.
Process each chunk to completion before starting the next. Do not stop mid-source unless the user explicitly approves an early exit.
5. Merge all reviewed chunks:
cat /tmp/anki-chunk-*.yaml > /tmp/anki-notes.yaml6. Run preflight:
python3 "$PIPELINE" preflight --deck "<deck>"7. Run add pipeline:
python3 "$PIPELINE" add-notes \
--deck "<deck>" \
--notes-file "/tmp/anki-notes.yaml" \
--source-identity "<source-url-or-path-or-title>" \
--source-text-file "/tmp/source.txt"8. Return succinct report from script output.
Always run — for sources ≤2,500 words, produce a single-chunk plan.
/tmp/source.txt./tmp/anki-source-metrics-<hash>.yaml:source_hash: "6f0fa16a8c25"
total_words: 8303
sections:
- heading: "§1. Introduction"
words: 225
- heading: "§2. Manifesto"
words: 300/tmp/anki-chunk-plan-<hash>.yaml:source_hash: "6f0fa16a8c25"
total_words: 8303
card_target_min: 41
card_target_max: 83
chunks:
- id: 1
sections: "§1–§5"
approx_words: 2100
card_min: 10
card_max: 21
status: pendingThe hash is the first 12 characters of sha256(normalized_source_identity + "\n" + normalized_source_text) — the same value the pipeline script computes internally.
After writing /tmp/anki-chunk-N.yaml, build and run the evaluator once. This is mandatory for every chunk and every card before anything is added to Anki. A rewritten chunk does not need to be evaluated again unless the evaluator failed/incompletely reviewed it or the user explicitly requests another pass. Template: Evaluator prompt
PROMPT=$(python3 -c "
import sys
t = open(sys.argv[1]).read()
c = open(sys.argv[2]).read()
print(t.replace('{{CHUNK_YAML}}', c))
" "$REFS/03-evaluator-prompt.md" "/tmp/anki-chunk-N.yaml")
timeout 200 pi --mode json --no-session --no-skills --no-extensions \
--no-tools --no-context-files \
--model opencode-go/glm-5.1 "$PROMPT" 2>/dev/null \
| jq -rj 'select(.type=="message_update" and .assistantMessageEvent.type=="text_delta") | .assistantMessageEvent.delta'The evaluator returns three sections: a card-by-card verdict, a chunk-level synthesis (coverage gaps, ratio, systematic patterns, interference), and a concrete action list. Read all three before rewriting the chunk. Evaluate the feedback critically — the evaluator can be wrong, over-strict, or miss domain context. Accept findings that improve clarity and retrieval; push back on those that would make cards worse.
If the evaluator fails, times out, or cannot review the full chunk, stop and ask the user whether to reduce chunk size, change evaluator model, or abort. Do not add cards from a chunk that has not received evaluator review.
Notes files are YAML lists. Always double-quote all field values — this single rule prevents all YAML parse errors (colons in values, boolean-like words, and {{...}} syntax are all safe inside double quotes).
# Section comments are native in YAML — use them freely
# === Chunk 1: §1–§5 Foundations (2,100 words) | target: 10–21 cards ===
- modelName: Cloze
fields:
Text: "Warmth is judged before {{c1::competence}}."
Back Extra: "Example: In a kickoff meeting, a technically strong answer can still land poorly if it sounds dismissive before trust exists."
tags: [warmth-competence]
- modelName: Basic
fields:
Front: "Why lead with warmth?"
Back: "Competence-first signaling reads as cold before trust is established."
tags: [warmth-competence]Rules:
modelName must be Cloze or Basic.Cloze fields: Text and Back Extra.Basic fields: Front and Back.tags: optional flow sequence [tag1, tag2].Where applicable, include a brief clarifying example on the back side of the card:
Basic, put it in Back.Cloze, put it in Back Extra.Use examples when they make an abstract idea concrete, distinguish likely-confused concepts, show application, or clarify a "why/how" answer. Omit examples for simple facts, dates, names, already-concrete definitions, or cases where the example would become the thing being memorized. Keep examples short and subordinate to the answer; do not turn the prompt into "give an example" unless example generation is itself the skill being trained.
Cards must be comprehensible in isolation. Assume the reviewer sees only the card prompt (Front for Basic, Text for Cloze) — not deck name, tags, or source metadata.
Before keeping a card, run this check: if this prompt appeared alone in a mixed-deck review session, would the topic be unambiguous? If not, add topic context directly to the prompt (prefix, field label, or context woven into the sentence).
Do not reference the source artifact.
❌ "this guide", "the guide", "this article", "the author says", "in the text/document", or any proper name unique to a worked example in the source (system names, fictional entities, organisation names used only as examples).
✅ Rewrite to domain wording with explicit topic context when needed: "In threat modeling…", "For REST APIs…", "In electronics…", "When designing…"
Do not write or use scripts to generate card prompts, cloze deletions, Basic fronts/backs, or other note contents from the source. Mechanical extraction creates plausible-looking but unreviewed cards and is prohibited.
The add pipeline script is allowed only after all card contents have been manually written, evaluated, and rewritten as needed.
Basic: Front, Back; Cloze: Text, Back Extra)sha256(normalized_identity + "\n" + normalized_text))/tmp/anki-add-run-<hash>-<deck>.yamlpending|in_progress|done|failed)canAddNotesWithErrorDetail)\n → <br> in all fields)Front/Text > 220 chars; Back/Back Extra > 600 charsCalibration checks:
python3 "$PIPELINE" resume-status --checklist "/tmp/anki-add-run-<hash>-<deck>.yaml"Re-run the same add-notes command to resume unfinished execution chunks.
Skip non-addable notes and continue. Do not fail the run for duplicates.
If script use is impossible: version, modelNames, modelFieldNames, deckNames, createDeck, canAddNotesWithErrorDetail, addNotes.
<deck><n><min> / <max>/tmp/anki-source-metrics-<source-hash>.yaml/tmp/anki-chunk-plan-<source-hash>.yaml<n> / <n><n> / <n><min> / <max><n><n><n><n><n><n><source::...><batch::...>/tmp/anki-add-run-<hash>-<deck>.yaml~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.