render-finance-dashboard — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited render-finance-dashboard (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.
You render the booky finance dashboard from the current state of data/finance.db. The visual design is fixed by the template; you only fill it with data. The mechanical part (SQL → HTML, live-price fetch, asset inlining) lives in scripts/render_dashboard.py — invoke it, don't re-derive it.
scripts/render_dashboard.py{{NAME}} form): templates/dashboard.html.tpltemplates/styles.css — inlined into the HTML at render timetemplates/charts.js — inlined into the HTMLscripts/bundle-assets.py):templates/vendor/chart.umd.min.jstemplates/vendor/chartjs-adapter-date-fns.bundle.min.jstemplates/vendor/fonts-inline.css (EB Garamond + Cormorant Garamond, base64 woff2)[telegram] section of .secrets/findash (bot_token=… and chat_id=…)data/finance.dboutput/dashboard.htmldocs/sqlite-schema.mddocs/design-system.md python3 scripts/render_dashboard.pyThe script handles everything mechanical:
USD/ILS, GBP/ILS FX rates from Yahoo Finance (query1.finance.yahoo.com/v8/finance/chart/{symbol}). User-Agent header required.RR.LSE → RR.L. Quote units: USD direct; LSE pence (÷100 → GBP); TASE agorot (÷100 → ILS).prices and the new FX into fx_rates so a history accumulates day-by-day.closed_on IS NOT NULL from Cash and from the headline (they still show in SQLite-data).output/dashboard.html and a small meta file at /tmp/dashboard_meta.json (used by the Telegram step).If any vendor file is missing, the script stops with a clear message. Run python3 scripts/bundle-assets.py once to fix.
unattended daily claude -p run can run it without per-call approval (it can't build the read-secret + curl send inline — the permission analyzer won't auto-approve a command that sources .secrets and expands ${bot_token}, and the Write tool isn't granted unattended). The token is read at runtime and never printed.
scripts/send_telegram.sh # add: --note "<line>" to append a caption lineWhat it does (= the old steps 2+3, now deterministic):
output/dashboard.html as a document, caption Finance — <AS_OF_DATE> · <net worth>(literal · U+00B7), read from /tmp/dashboard_meta.json.
data/last_sync_summary.md exists, prepends Sync — <AS_OF_DATE> and sends it assendMessage (plain text; split into ≤4000-char parts on \n boundaries), then deletes it on success. Absent → prints Sync summary: Skipped (no summary).
[telegram] in .secrets/findash) → prints Telegram delivery skipped: … and exits 0 (localfile still useful). Never deletes the local dashboard on a Telegram failure.
Pass --note "<line>" to append a caption line — the morning flow uses this to surface a best-effort fetch failure. The script prints Sent to chat <id> / Telegram delivery failed: <description> / the Sync summary: … line — relay them in step 3.
output/dashboard.html.Sent to chat <chat_id>, Telegram delivery skipped: …, or Telegram delivery failed: <description>.Sync summary: Sent (<N> bullets), Sync summary: Skipped (no summary), or Sync summary: Failed: <description>.FAILED: — flag them so the user knows which positions fell back to cost basis).styles.css and the template. Don't add inline styles, classes, or markup not already defined.dir="auto" on table cells is already handled by the script.~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.