finance-news
Market news briefings with AI summaries. Use when asked about stock news, market updates, portfolio performance, morning/evening briefings, financial headlines, or price alerts. Supports US/Europe/Japan markets, WhatsApp delivery, and English/German output.
+ 1 more
Potentially suspicious implementation signals detected: rm -rf, password.
โ๏ธ Quick review
Finance News looks aimed at market news briefings with AI summaries. Follow-on functionality checks currently show first observed failure, the trust label is High Risk, and setup looks advanced.
This note is generated from the latest receipts and refreshed when the testing engine touches the skill again.
RatioDaemon on Finance News
Full commentary lives in the editorial lane so this skill page can stay focused on the evidence, setup guidance, and technical receipts.
baseline safety checks passed8/8 passedclean historyshow baseline lane summary
follow-on functionality checks failed15/17 passedfirst failed run seen for this laneshow follow-on lane summary
Before you install
- You are specifically looking for communication / awesome-index workflows.
- Expect setup work: this skill references 12 env vars.
- Assume outside service calls are part of the story: 12 external domain references showed up.
- Expect local command execution or subprocess behavior, not just polite in-memory logic.
- functionality-v2 found trouble, so treat this like a review-first install instead of a casual click.
- Suspicious signals are present; this is not just a broader capability surface doing ordinary work.
- The capability surface is non-trivial: this skill touches higher-privilege or higher-impact areas.
Why this label
This landed in High Risk because suspicious patterns or dangerous signal combinations outweighed ordinary provenance and utility clues.
Uncertainty: Source-level evidence helps, but this is still largely static-analysis-first unless a manual review is present.
Capability surface and suspicious signals
Capability surface
These increase access or impact, but they are not the same thing as deceptive or malicious behavior.
Capability summary
+ 3 more
Suspicious behaviors
These are the signals that count much more heavily against the score.
Evidence
+ 9 more
+ 9 more
+ 3 more
+ 2 more
Read this section in two layers: capability surface shows what the skill can touch, while suspicious signals show what looks deceptive or riskier than ordinary integrations.
๐งช Technical runtime details
This is the raw runtime layer: baseline-v3 first, then the follow-on lane when available. The postcard above is the fast read; the receipts below are the technical view.
This is the follow-on adaptive lane: source-aware smoke checks for the file types actually present in this skill after it already cleared baseline-v3. Depending on the repo shape, that can include manifest identity, package entrypoints, docs-link integrity, shipped fixture validation, and real help-smoke runs.
1a429e80664b2aa796a44d05843e4528c30d5c02e1759a51808b540bde7d70d5๐งญ skill structurestatus: passedpassedexit 0235 mstap for adaptive receipts
sh -lc test -s /source/SKILL.md && grep -Eq "^#{1,6} " /source/SKILL.md && echo skill-structure-okskill-structure-okโ๐ชช _meta.json shapestatus: passedpassedexit 0238 mstap for adaptive receipts
node -e const fs=require("fs"); const files=process.argv.slice(1); for (const file of files) { const meta=JSON.parse(fs.readFileSync(file, "utf8")); if (!meta || Array.isArray(meta) || typeof meta !== "object") throw new Error(`${file}: _meta.json must be an object`); if (typeof meta.owner !== "string" || !meta.owner) throw new Error(`${file}: owner missing`); if (typeof meta.slug !== "string" || !meta.slug) throw new Error(`${file}: slug missing`); if (!meta.latest || typeof meta.latest !== "object") throw new Error(`${file}: latest missing`); if (typeof meta.latest.version !== "string" || !meta.latest.version) throw new Error(`${file}: latest.version missing`); if (typeof meta.latest.publishedAt !== "number") throw new Error(`${file}: latest.publishedAt missing`); } console.log(`meta-json-shape-ok:${files.length}`); /source/_meta.jsonmeta-json-shape-ok:1โ๐งฌ _meta.json identitystatus: passedpassedexit 0240 mstap for adaptive receipts
node -e const fs=require("fs"); const expectedOwner=process.argv[1]; const expectedSlug=process.argv[2]; const files=process.argv.slice(3); for (const file of files) { const meta=JSON.parse(fs.readFileSync(file, "utf8")); if (meta.owner !== expectedOwner) throw new Error(`${file}: owner mismatch ${meta.owner} !== ${expectedOwner}`); if (meta.slug !== expectedSlug) throw new Error(`${file}: slug mismatch ${meta.slug} !== ${expectedSlug}`); if (meta.history && !Array.isArray(meta.history)) throw new Error(`${file}: history must be an array`); for (const entry of meta.history || []) { if (typeof entry.version !== "string" || !entry.version) throw new Error(`${file}: history.version missing`); if (typeof entry.publishedAt !== "number") throw new Error(`${file}: history.publishedAt missing`); } } console.log(`meta-json-identity-ok:${files.length}`); kesslerio finance-news /source/_meta.jsonmeta-json-identity-ok:1โ๐งพ json parsestatus: passedpassedexit 0255 mstap for adaptive receipts
node -e const fs=require("fs"); const files=process.argv.slice(1); for (const file of files) JSON.parse(fs.readFileSync(file, "utf8")); console.log(`json-parse-ok:${files.length}`); /source/_meta.json /source/config/config.json /source/config/manual_earnings.json /source/htmlcov/status.jsonjson-parse-ok:4โ๐ shell syntaxstatus: passedpassedexit 0223 mstap for adaptive receipts
bash -lc for file do bash -n "$file"; done && echo shell-syntax-ok:$# functionality-shell /source/cron/alerts.sh /source/cron/earnings-weekly.sh /source/cron/earnings.sh /source/cron/evening.sh /source/cron/morning.sh /source/scripts/venv-setup.shshell-syntax-ok:6โ๐ python syntaxstatus: passedpassedexit 0401 mstap for adaptive receipts
python3 -c import ast, pathlib, sys; files=sys.argv[1:]; [ast.parse(pathlib.Path(file).read_text(encoding="utf-8"), filename=file) for file in files]; print(f"python-syntax-ok:{len(files)}") /source/scripts/alerts.py /source/scripts/briefing.py /source/scripts/earnings.py /source/scripts/fetch_news.py /source/scripts/portfolio.py /source/scripts/ranking.py /source/scripts/research.py /source/scripts/setup.py /source/scripts/stocks.py /source/scripts/summarize.py /source/scripts/translate_portfolio.py /source/scripts/utils.py /source/tests/test_alerts_extended.py /source/tests/test_alerts.py /source/tests/test_briefing.py /source/tests/test_earnings.py /source/tests/test_fetch_news.py /source/tests/test_portfolio.py /source/tests/test_ranking.py /source/tests/test_research.py /source/tests/test_setup.py /source/tests/test_stocks.py /source/tests/test_summarize.pypython-syntax-ok:23โ๐ข node syntaxstatus: passedpassedexit 0241 mstap for adaptive receipts
sh -lc for file do node --check "$file"; done && echo node-syntax-ok:$# functionality-node /source/htmlcov/coverage_html_cb_dd2e7eb5.jsnode-syntax-ok:1โ๐งช yaml parsestatus: passedpassedexit 0281 mstap for adaptive receipts
eval . /source/workflows/alerts-cron.yaml# Price Alerts Workflow for Cron (No Approval Gate)
# Usage: lobster run --file workflows/alerts-cron.yaml --args-json '{"lang":"en"}'
#
# Schedule: 2:00 PM PT / 5:00 PM ET (1 hour after market close)
# Checks price alerts against current prices (including after-hours)
name: finance.alerts.cron
description: Check price alerts and send triggered alerts to WhatsApp/Telegram
args:
lang:
default: en
description: "Language: en or de"
channel:
default: "${FINANCE_NEWS_CHANNEL:-whatsapp}"
description: "Delivery channel: whatsapp or telegram"
target:
default: "${FINANCE_NEWS_TARGET}"
description: "Target: group name, JID, or chat ID"
steps:
# Check alerts against current pricesโ๐งช yaml parsestatus: passedpassedexit 0229 mstap for adaptive receipts
eval . /source/workflows/briefing-cron.yaml# Finance Briefing Workflow for Cron (No Approval Gate)
# Usage: lobster run --file workflows/briefing-cron.yaml --args-json '{"time":"morning","lang":"de"}'
#
# This workflow:
# 1. Generates a market briefing via Docker
# 2. Translates portfolio headlines (German)
# 3. Sends directly to messaging channel (no approval)
name: finance.briefing.cron
description: Generate market briefing and send to WhatsApp/Telegram (auto-approve for cron)
args:
time:
default: morning
description: "Briefing type: morning or evening"
lang:
default: de
description: "Language: en or de"
channel:
default: "${FINANCE_NEWS_CHANNEL:-whatsapp}"
description: "Delivery channel: whatsapp or telegram"โ๐งช yaml parsestatus: passedpassedexit 0231 mstap for adaptive receipts
eval . /source/workflows/briefing.yaml# Finance Briefing Workflow for Lobster
# Usage: lobster "workflows.run --file workflows/briefing.yaml --args-json '{\"time\":\"morning\",\"lang\":\"de\"}'"
#
# This workflow:
# 1. Generates a market briefing via Docker
# 2. Halts for approval before sending
# 3. Sends to messaging channel after approval
name: finance.briefing
description: Generate market briefing and send to WhatsApp/Telegram with approval gate
args:
time:
default: morning
description: "Briefing type: morning or evening"
lang:
default: de
description: "Language: en or de"
channel:
default: "${FINANCE_NEWS_CHANNEL:-whatsapp}"
description: "Delivery channel: whatsapp or telegram"โ๐งช yaml parsestatus: passedpassedexit 0224 mstap for adaptive receipts
eval . /source/workflows/earnings-cron.yaml# Earnings Alert Workflow for Cron (No Approval Gate)
# Usage: lobster run --file workflows/earnings-cron.yaml --args-json '{"lang":"en"}'
#
# Schedule: 6:00 AM PT / 9:00 AM ET (30 min before market open)
# Sends today's earnings calendar to WhatsApp/Telegram
name: finance.earnings.cron
description: Send earnings alerts for today's reports
args:
lang:
default: en
description: "Language: en or de"
channel:
default: "${FINANCE_NEWS_CHANNEL:-whatsapp}"
description: "Delivery channel: whatsapp or telegram"
target:
default: "${FINANCE_NEWS_TARGET}"
description: "Target: group name, JID, or chat ID"
steps:
# Check earnings calendar for today and this weekโ๐งช yaml parsestatus: passedpassedexit 0228 mstap for adaptive receipts
eval . /source/workflows/earnings-weekly-cron.yaml# Weekly Earnings Alert Workflow for Cron (No Approval Gate)
# Usage: lobster run --file workflows/earnings-weekly-cron.yaml --args-json '{"lang":"en"}'
#
# Schedule: Sunday 7:00 AM PT (before market week starts)
# Sends upcoming week's earnings calendar to WhatsApp/Telegram
name: finance.earnings.weekly.cron
description: Send weekly earnings preview for portfolio stocks
args:
lang:
default: en
description: "Language: en or de"
channel:
default: "${FINANCE_NEWS_CHANNEL:-whatsapp}"
description: "Delivery channel: whatsapp or telegram"
target:
default: "${FINANCE_NEWS_TARGET}"
description: "Target: group name, JID, or chat ID"
steps:
# Check earnings calendar for upcoming weekโ๐งฎ csv parsestatus: passedpassedexit 0320 mstap for adaptive receipts
python3 -c import csv, pathlib, sys
files=sys.argv[1:]
for file in files:
rows=list(csv.reader(pathlib.Path(file).open(encoding="utf-8", newline="")))
if not rows:
raise SystemExit(f"{file}: empty csv")
print(f"csv-parse-ok:{len(files)}") /source/tests/fixtures/sample_portfolio.csvโโ๐ pyproject parsestatus: passedpassedexit 0355 mstap for adaptive receipts
python3 -c import pathlib, sys, tomllib; files=sys.argv[1:]; [tomllib.loads(pathlib.Path(file).read_text(encoding="utf-8")) for file in files]; print(f"pyproject-toml-parse-ok:{len(files)}") /source/pyproject.tomlpyproject-toml-parse-ok:1โ๐ requirements.txt shapestatus: failedexpectation_failedexit 0318 mstap for adaptive receipts
python3 -c import pathlib, re, sys
allowed_prefixes=("-r ","--requirement ","-c ","--constraint ","-e ","--editable ","--index-url ","--extra-index-url ","--find-links ","--trusted-host ","--no-binary ","--only-binary ")
pattern=re.compile(r"^[A-Za-z0-9_.-]+(?:[[A-Za-z0-9_.,-]+])?(?:s*(?:==|>=|<=|~=|>|<|!=)s*[^s#;]+)?(?:s*;.*)?$")
files=sys.argv[1:]
for file in files:
for idx,line in enumerate(pathlib.Path(file).read_text(encoding="utf-8").splitlines(), start=1):
stripped=line.strip()
if not stripped or stripped.startswith("#"):
continue
if stripped.startswith(allowed_prefixes) or "://" in stripped or " @ " in stripped:
continue
if not pattern.match(stripped):
raise SystemExit(f"{file}:{idx}: malformed requirement line: {stripped}")
print(f"requirements-txt-shape-ok:{len(files)}") /source/requirements.txtโโ๐ python help smokestatus: failedruntime_failedexit 11420 mstap for adaptive receipts
sh -lc for file do python3 "$file" --help >/dev/null 2>&1 || python3 "$file" -h >/dev/null 2>&1 || exit 1; done && echo python-help-ok:$# functionality-python-help /source/scripts/alerts.py /source/scripts/briefing.py /source/scripts/earnings.py /source/scripts/fetch_news.py /source/scripts/portfolio.py /source/scripts/research.pyโโ๐ docs link integritystatus: passedpassedexit 0298 mstap for adaptive receipts
python3 -c import pathlib, re, sys
root=pathlib.Path("/source").resolve()
pattern=re.compile(r"[[^]]+](([^)]+))")
missing=[]
checked=0
for file in [pathlib.Path(p) for p in sys.argv[1:]]:
try:
text=file.read_text(encoding="utf-8")
except Exception:
continue
for target in pattern.findall(text):
target=target.strip().strip("<>")
if not target or target.startswith(("http://","https://","mailto:","#")):
continue
target=target.split("#",1)[0].strip()
if not target:
continue
checked += 1
resolved=(file.parent / target).resolve()
try:
resolved.relative_to(root)
except ValueError:
missing.append(f"{file}: outside-source link -> {target}")
continue
if not resolved.exists():
missing.append(f"{file}: missing -> {target}")
if missing:
raise SystemExit("\n".join(missing[:20]))
print(f"docs-local-links-ok:{checked}") /source/docs/EQUITY_SHEET_FIXES.md /source/docs/PREMIUM_SOURCES.md /source/README.md /source/SKILL.md /source/tests/README.md /source/workflows/README.mdโโ1a429e80664b2aa796a44d05843e4528c30d5c02e1759a51808b540bde7d70d5๐ฆ Source mountstatus: passedpassedexit 0266 mstap for the raw receipts
sh -lc find /source -maxdepth 2 -type f | sort | sed -n "1,12p" > /workspace/source-files.txt && wc -l /workspace/source-files.txt && cat /workspace/source-files.txtbusybox@sha256:b9598f8c98e24d0ad42c1742c32516772c3aa2151011ebaf639089bd18c605b8a014c1b7613ac03f4c1ccfb86e3248b688433cfd49e7cdd4f66659c571d48fd1e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855Observed stdout:
12 /workspace/source-files.txt /source/README.md /source/SKILL.md /source/_meta.json /source/config/config.json /source/config/manual_earnings.json /source/cron/alerts.sh /source/cron/earnings-weekly.sh /source/cron/earnings.sh /source/cron/evening.sh /source/cron/morning.sh /source/docs/EQUITY_SHEET_FIXES.md /source/docs/PREMIUM_SOURCES.md
Observed stderr:
(empty)
Workspace artifacts:
- source-files.txt (312 B)
๐ Source write guardstatus: passedpassedexit 0270 mstap for the raw receipts
sh -lc touch /source/driftbot-write-test >/tmp/source-write.out 2>&1 || true; if grep -Eiq "Read-only file system|Permission denied" /tmp/source-write.out || [ ! -e /source/driftbot-write-test ]; then echo source-readonly; fibusybox@sha256:b9598f8c98e24d0ad42c1742c32516772c3aa2151011ebaf639089bd18c605b8a65af92097dc754e9cac4a455c5378d78b05e7927705ae45e1d20a24c4c1fd3ce3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855Observed stdout:
source-readonly
Observed stderr:
(empty)
Workspace artifacts:
No workspace artifacts produced.
๐ Workspace writestatus: passedpassedexit 0246 mstap for the raw receipts
sh -lc echo workspace-ok > /workspace/write-check.txt && grep -q "workspace-ok" /workspace/write-check.txt && echo workspace-write-okbusybox@sha256:b9598f8c98e24d0ad42c1742c32516772c3aa2151011ebaf639089bd18c605b881487f7df7b83c1d3fae9c36fb1009328fa34feca0f5c1581674de4cba29e6f5e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855Observed stdout:
workspace-write-ok
Observed stderr:
(empty)
Workspace artifacts:
- write-check.txt (13 B)
๐ Hostname network denialstatus: passedpassedexit 0251 mstap for the raw receipts
sh -lc wget -T 3 -qO- http://example.com >/tmp/http-host.out 2>&1 || true; grep -Eiq "bad address|network is unreachable|timed out|failed|refused" /tmp/http-host.out && echo network-host-blockedbusybox@sha256:b9598f8c98e24d0ad42c1742c32516772c3aa2151011ebaf639089bd18c605b8aa4c95f392f2c19669ae67769237c23b54efb5f5e26a8ac8f11162ef28e7f141e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855Observed stdout:
network-host-blocked
Observed stderr:
(empty)
Workspace artifacts:
No workspace artifacts produced.
๐งฑ Raw-IP network denialstatus: passedpassedexit 0237 mstap for the raw receipts
sh -lc wget -T 3 -qO- http://1.1.1.1 >/tmp/http-ip.out 2>&1 || true; grep -Eiq "bad address|network is unreachable|timed out|failed|refused" /tmp/http-ip.out && echo network-ip-blockedbusybox@sha256:b9598f8c98e24d0ad42c1742c32516772c3aa2151011ebaf639089bd18c605b8ee48345f6e97282a8b1f42753df3c9b37886403c60b09a044657b95126bae8b1e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855Observed stdout:
network-ip-blocked
Observed stderr:
(empty)
Workspace artifacts:
No workspace artifacts produced.
๐งช Fake-env handlingstatus: passedpassedexit 0234 mstap for the raw receipts
sh -lc env | grep -E "OPENAI_API_KEY|SLACK_BOT_TOKEN|GITHUB_TOKEN" | sed "s/=.*$/=REDACTED/"busybox@sha256:b9598f8c98e24d0ad42c1742c32516772c3aa2151011ebaf639089bd18c605b8d714e2d3c2043f53d26d2deebac9b26a17f96f8d20158469b586bb598bc80c57e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855Observed stdout:
GITHUB_TOKEN=REDACTED SLACK_BOT_TOKEN=REDACTED OPENAI_API_KEY=REDACTED
Observed stderr:
(empty)
Workspace artifacts:
No workspace artifacts produced.
๐๏ธ Secret-path isolationstatus: passedpassedexit 0230 mstap for the raw receipts
sh -lc test ! -e /root/.ssh && test ! -e /home/claw1/.ssh && test ! -e /workspace/.ssh && echo no-host-secretsbusybox@sha256:b9598f8c98e24d0ad42c1742c32516772c3aa2151011ebaf639089bd18c605b8e95cf953e01cafd431be70f0f5539c4c0ae8961ef5cff96d968a29509597c797e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855Observed stdout:
no-host-secrets
Observed stderr:
(empty)
Workspace artifacts:
No workspace artifacts produced.
๐ณ Docker socket denialstatus: passedpassedexit 0224 mstap for the raw receipts
sh -lc test ! -S /var/run/docker.sock && echo no-docker-socketbusybox@sha256:b9598f8c98e24d0ad42c1742c32516772c3aa2151011ebaf639089bd18c605b8702d41c3742c72aff24f584ad0138f2df38b424090d03d3b3e85e3212f0df2efe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855Observed stdout:
no-docker-socket
Observed stderr:
(empty)
Workspace artifacts:
No workspace artifacts produced.
What this proves: the skill really executed inside the isolated worker, under the listed sandbox constraints, with captured output and artifacts. What this does not prove: comprehensive safety, benign intent in every context, or correctness under real credentials and live network access.
Publisher and provenance
Listed in the VoltAgent awesome-openclaw-skills catalog under Communication and lightly source-scanned from openclaw/skills. This is stronger evidence than catalog metadata alone, but still not a full runtime audit.
Source type: awesome-index
Source path: https://github.com/openclaw/skills/tree/main/skills/kesslerio/finance-news/SKILL.md
Source URL: https://github.com/openclaw/skills/tree/main/skills/kesslerio/finance-news/SKILL.md
Discovery category: Communication
Manual review
No human review yet. The scorecard is currently static-analysis-first.
Community signals
Community signals
These are community attention markers, not crowd-sourced truth. Click what feels especially worth flagging or reviewing.
Related skills
kefir-batch-manager
Comprehensive kรฉfir batch management system with cycle tracking, intelligent reminders, grain health monitoring, and recipe management. Use when managing kรฉfir fermentation cycles, tracking grain health, calculating ratios, scheduling reminders, or maintaining fermentation records.
echo-agent
EchoAgent is a minimal OpenClaw-compatible skill.
japanese-tutor
Interactive Japanese learning assistant. Supports vocabulary, grammar, quizzes, roleplay, PDF/DOCX material parsing for study/homework help, and OCR translation.