fill-icmje-coi — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited fill-icmje-coi (Agent Skill) and scored it 91/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 1 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 1 flagged
The text {match} is the classic direct prompt-injection phrasing. Placed in a skill body that the agent reads as trusted instructions, it tries to make the agent abandon its prior rules and follow whatever comes next — a full system-prompt override.
ignore/disregard/forget … previous instructions sentence.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.
The official ICMJE coi_disclosure.docx keeps every field inside Word Content Controls (SDTs), which python-docx cell.text silently ignores. The script therefore does literal-string replacement in word/document.xml, which only works when the target strings already exist — hence the shipped pre-filled synthetic seed.
seed, because programmatic Content Controls are fragile and Word-version-dependent. If an error seems to require altering the seed structure, stop and escalate to the user.
templates/icmje_coi_seed_synthetic.docx is PII-scrubbed (synthetic name, title, date; metadata ICMJE / Anonymous); real-person seeds leak PII through both document.xml and docProps. Keep custom seeds with real names in private per-project directories, and before promoting any seed check unzip -p seed.docx docProps/core.xml for real names.
Date, Name and Title; the ☒ None entries come from the seed unchanged. Never say the script "handled the disclosures": it cloned the seed, and no author-specific disclosure reasoning happened. An author with a real disclosure edits their own form in Word.
template.
Skip this skill when the target journal uses its own declaration form (Elsevier Declaration of Interest, a BMJ ICMJE derivative, etc.) rather than the canonical ICMJE form — check the author guidelines first.
Ask the user (or extract from the conversation):
[(1, "Author One"), (2, "Author Two"), ...],taken verbatim from the manuscript title page or the user's list
submission/{journal}/icmje_forms/Gate 1 — user approval. Present the intake back before generating anything. Name which authors will get all-None forms and remind the user that anyone with a real disclosure must fill their own form in Word instead.
python3 ${CLAUDE_SKILL_DIR}/scripts/fill_icmje_coi.py \
--seed ${CLAUDE_SKILL_DIR}/templates/icmje_coi_seed_synthetic.docx \
--seed-name "Placeholder Author" \
--seed-title "Placeholder Manuscript Title" \
--seed-date "January 1, 2000" \
--new-title "{exact manuscript title}" \
--new-date "{submission date}" \
--out-dir {out_dir} \
--authors '[[1,"Author One"],[2,"Author Two"],...]'It writes one ICMJE_COI_{NN}_{Name}.docx per author and exits nonzero if any seed string is not found. It exits 2, before writing anything, if any --seed-* or --new-* value or author name is empty: an empty seed string would match nothing and leave the seed's value in every form.
For each generated docx confirm: ☒ count = 14 (13 disclosure items + final certification); "None" disclosures = 13; the correct name after "Your Name:" and title after "Manuscript Title:"; no seed strings left. SEED must be the exact --seed-name, --seed-title and --seed-date values used in Phase 2 (the shipped placeholders below, or a custom seed's own strings); TITLE must be the --new-title value.
python3 - {out_dir}/*.docx <<'PY'
import sys, zipfile
SEED = ("Placeholder Author", "Placeholder Manuscript Title", "January 1, 2000") # = --seed-* values
TITLE = "{exact manuscript title}" # = --new-title
assert all(s.strip() for s in SEED) and TITLE.strip(), "empty SEED/TITLE value"
for f in sys.argv[1:]:
xml = zipfile.ZipFile(f).read("word/document.xml").decode("utf-8")
assert xml.count("☒") == 14, f"{f}: bad ☒ count"
assert xml.count(">None<") + xml.count(">None ") == 13, f"{f}: bad None count"
for ph in SEED:
assert ph not in xml, f"{f}: seed leak {ph!r}"
t = TITLE.replace("&", "&").replace("<", "<").replace(">", ">")
assert t in xml, f"{f}: title missing"
print("✓", f)
PYThis snippet does not locate the name inside the "Your Name:" field; confirm the name by opening each form.
Gate 2 — user review. Present the verification results before handing off the files.
Give the user this copy to send with each personalized form, written in the co-authors' language:
Please review the attached ICMJE COI form. - If the contents are correct, sign and reply with a PDF. - If a change is needed, edit/check the relevant item, sign, and reply. - If there are no changes at all, reply "no changes" and return the signed PDF separately.
All authors can be emailed in one draft batch (e.g., gws gmail draft). Gate 3 — the user approves the batch before anything is sent.
Read ${CLAUDE_SKILL_DIR}/references/seeds.md when the user wants a custom seed (different default wording, a common grant pre-filled in items 2/3) or asks how the shipped seed was made.
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.