agentleFS
B-M-Capital-ResearchB-M-Capital-Research/honeclaw/.agents/skills/event-engine-push-review/SKILL.md

event-engine-push-review

Skill748 starsChanged 3 months agoMITView on GitHub

Use in the honeclaw repository when Codex needs to review event-engine push quality for one or more actors: what each user/channel received, whether push timing and digest grouping were reasonable, whether messages were duplicated or useless, and whether useful events were filtered, omitted, capped, cooled down, or left undelivered.

We split this skill into the rules it gives an agent

16 rules. About 0 are common, 11 are distinctive, and 5 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈11

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 5

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Write a short todo before running commands:

    line 12
  2. Distinctive:

    Check the worktree first:

    line 19
  3. Distinctive:

    Do not commit private runtime DBs, ignored calibration exports, full article bodies, or user portfolio files unless the user explicitly …

    line 25
  4. Very specific:

    Default timezone is Asia/Shanghai.

    line 29
  5. Very specific:

    If the user says "everyone", review each actor that has sink, digest, digest_item, global_digest_item, prefs, or router rows in the window.

    line 50
  6. Distinctive:

    Use the repository exporter for one actor/day:

    line 54
  7. Very specific:

    Use --include-body only when the body text is needed to judge render quality or duplicate digest copy.

    line 63
  8. Distinctive:

    Read actor prefs before judging timing:

    line 104
  9. Distinctive:

    Look for repeated event ids:

    line 135
  10. Distinctive:

    Look for repeated titles/facts:

    line 156
  11. Distinctive:

    Keep the final review concise and evidence-backed:

    line 251
  12. Very specific:

    Keep committed reports concise.

    line 294
  13. Distinctive:

    If the review identifies a durable bug or baseline case:

    line 298
  14. Very specific:

    Use event-engine-baseline-testing before changing event-engine code, fixtures, or LLM classifier expectations.

    line 300
  15. Distinctive:

    Add only durable public sample fields to baseline fixtures.

    line 301
  16. Distinctive:

    Keep raw daily exports ignored and out of commits.

    line 302

≈ “Common” is an estimate: at least 1 in 5 of the 308,232 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Event Engine Push Review

Review real delivery evidence from the authoritative PostgreSQL event store. Treat this as an audit task, not a rewrite task. Prefer read-only exports and SQL first; only change code or fixtures after the user agrees on a durable failure pattern.

Start Checklist

Write a short todo before running commands:

  1. Goal: actor(s), local date/window, and review question.
  2. Files/data: PostgreSQL events / delivery_log, actor preferences/portfolio rows, and ignored exports under data/exports/event-engine-calibration/.
  3. Verification: read-only export/query commands; if code or baselines change, also use event-engine-baseline-testing.
  4. Documentation: update active event-engine plan only when the review leads to a durable behavior change; one-off audit exports do not need plan updates.

Check the worktree first:

git status --short --branch

Do not commit private runtime DBs, ignored calibration exports, full article bodies, or user portfolio files unless the user explicitly asks and the repo policy allows it.

Identify Actors And Window

Default timezone is Asia/Shanghai. For "last 24h", compute the exact UTC bounds and state them in the answer.

List active delivery actors in a local date window. Map the repository's HONE_POSTGRES_* connection variables to standard PG* variables first when the shell does not already provide them (see docs/runbooks/local-postgres-development.md):

psql -X -v ON_ERROR_STOP=1 -P pager=off -c "
WITH bounds AS (
  SELECT
    EXTRACT(EPOCH FROM TIMESTAMPTZ 'YYYY-MM-DD 00:00:00 Asia/Shanghai')::BIGINT AS start_ts,
    EXTRACT(EPOCH FROM TIMESTAMPTZ 'YYYY-MM-DD 00:00:00 Asia/Shanghai' + INTERVAL '1 day')::BIGINT AS end_ts
)
SELECT actor, channel, status, severity, COUNT(*) AS n
FROM delivery_log, bounds
WHERE sent_at_ts >= start_ts AND sent_at_ts < end_ts
GROUP BY actor, channel, status, severity
ORDER BY actor, channel, status, severity;
"

If the user says "everyone", review each actor that has sink, digest, digest_item, global_digest_item, prefs, or router rows in the window.

Export The Evidence

Use the repository exporter for one actor/day:

python3 scripts/diagnose_event_engine_daily_pushes.py \
  --date YYYY-MM-DD \
  --actor telegram::::8039067465 \
  --format both

Use --include-body only when the body text is needed to judge render quality or duplicate digest copy. The output directory is ignored:

data/exports/event-engine-calibration/

For quick terminal review, query sent rows directly:

psql -X -v ON_ERROR_STOP=1 -P pager=off -c "
WITH bounds AS (
  SELECT EXTRACT(EPOCH FROM now() - INTERVAL '24 hours')::BIGINT AS start_ts
)
SELECT
  to_char(to_timestamp(d.sent_at_ts) AT TIME ZONE 'Asia/Shanghai', 'YYYY-MM-DD HH24:MI:SS') AS sent_local,
  d.actor, d.channel, d.status, d.severity,
  e.title,
  substr(replace(coalesce(d.body,''), E'\n', ' '), 1, 180) AS body_preview
FROM delivery_log d
LEFT JOIN events e ON e.id = d.event_id, bounds
WHERE d.sent_at_ts >= bounds.start_ts
  AND d.status IN ('sent','dryrun','quiet_held','quiet_dropped')
ORDER BY d.actor, d.sent_at_ts, d.id;
"

Review Dimensions

Classify each suspect row with one of these labels:

  • useful: timely, relevant, readable, and appropriately routed.
  • noise: sent but low value, stale, generic, legal-ad/listicle/opinion-blog, or unrelated to the actor.
  • duplicate: repeated same event, same headline, same social text, same earnings countdown, or same fact across immediate + digest without a reason.
  • bad_timing: immediate should have been digest, digest should have been immediate, quiet-hours behavior was wrong, or digest slot timing was surprising.
  • should_filter: sent but should have been filtered by prefs/source/kind/portfolio-only/cooldown.
  • should_immediate: queued/digest/filtered but should have reached the sink immediately.
  • should_digest: filtered/no_actor/omitted but should have appeared in digest.
  • baseline_candidate: stable reusable classifier/router case worth adding to tests/fixtures/event_engine/.

Timing Checks

Read actor prefs before judging timing:

cat data/notif_prefs/<actor-file>.json

Check:

  • digest_slots and actor timezone: digest sends should cluster near configured slots.
  • quiet_hours: high events during quiet time should be held, bundled, or dropped only according to freshness rules.
  • immediate_kinds: configured immediate kinds should not resurrect Low-quality news.
  • price alerts: respect actor thresholds, cooldowns, band gaps, and shelf life.
  • macro: High macro should be immediate only inside due window; otherwise digest.
  • earnings/corp-action/macro prefetch: stale calendar rows should not dominate a slot.

Content Checks

Useful event-engine messages should answer: what happened, who it touches, why now, and where to inspect it.

Flag content problems when:

  • macro rows lack actual/expected/previous values and also lack a clear publish time.
  • earnings surprise rows lack metric names such as EPS.
  • news rows lack concrete links when the event has a URL.
  • render differs badly by channel: Telegram HTML, Discord embed, Feishu card, and iMessage/plain should each be readable in their native format.
  • digest body hides high-value items behind too many low-value items.
  • social/raw text is truncated into ambiguous fragments.
  • source labels are misleading, missing, or too generic for audit.

Duplicate Checks

Look for repeated event ids:

psql -X -v ON_ERROR_STOP=1 -P pager=off -c "
WITH bounds AS (
  SELECT EXTRACT(EPOCH FROM now() - INTERVAL '24 hours')::BIGINT AS start_ts
)
SELECT d.actor, d.event_id, d.channel, d.status, COUNT(*) AS n,
       to_char(to_timestamp(MIN(d.sent_at_ts)) AT TIME ZONE 'Asia/Shanghai', 'YYYY-MM-DD HH24:MI:SS') AS first_local,
       to_char(to_timestamp(MAX(d.sent_at_ts)) AT TIME ZONE 'Asia/Shanghai', 'YYYY-MM-DD HH24:MI:SS') AS last_local,
       e.title
FROM delivery_log d
LEFT JOIN events e ON e.id = d.event_id, bounds
WHERE d.sent_at_ts >= bounds.start_ts
  AND d.status IN ('sent','dryrun')
GROUP BY d.actor, d.event_id, d.channel, d.status
HAVING COUNT(*) > 1
ORDER BY n DESC, last_local DESC;
"

Look for repeated titles/facts:

psql -X -v ON_ERROR_STOP=1 -P pager=off -c "
WITH bounds AS (
  SELECT EXTRACT(EPOCH FROM now() - INTERVAL '24 hours')::BIGINT AS start_ts
)
SELECT d.actor, e.title, COUNT(*) AS n,
       string_agg(DISTINCT d.channel, ',') AS channels,
       string_agg(DISTINCT d.status, ',') AS statuses
FROM delivery_log d
JOIN events e ON e.id = d.event_id, bounds
WHERE d.sent_at_ts >= bounds.start_ts
  AND d.status IN ('sent','dryrun')
GROUP BY d.actor, lower(e.title)
HAVING COUNT(*) > 1
ORDER BY n DESC;
"

Manual duplicate judgment matters: immediate + later digest can be acceptable if the digest is a rollup and not a second alert; two identical sink pushes usually are not.

Useless Push Checks

Inspect sent rows with low value signals:

psql -X -v ON_ERROR_STOP=1 -P pager=off -c "
WITH bounds AS (
  SELECT EXTRACT(EPOCH FROM now() - INTERVAL '24 hours')::BIGINT AS start_ts
)
SELECT to_char(to_timestamp(d.sent_at_ts) AT TIME ZONE 'Asia/Shanghai', 'YYYY-MM-DD HH24:MI:SS') AS sent_local,
       d.actor, d.channel, d.severity, e.source, e.title, e.summary
FROM delivery_log d
JOIN events e ON e.id = d.event_id, bounds
WHERE d.sent_at_ts >= bounds.start_ts
  AND d.status IN ('sent','dryrun')
  AND (
    e.source ILIKE '%pr_wire%'
    OR e.source ILIKE '%opinion%'
    OR lower(e.title) LIKE '%shareholder alert%'
    OR lower(e.title) LIKE '%class action%'
    OR lower(e.title) LIKE '%deadline%'
  )
ORDER BY d.sent_at_ts DESC;
"

Also scan for:

  • generic analyst "hold/maintain" with no target change.
  • old earnings previews or repeated T-1/T-2/T-3 countdowns.
  • broad macro items with no relation to market-moving countries or indicators.
  • low-quality global news pushed to a portfolio-only actor.

Useful Filtered-Out Checks

Review omitted, queued, capped, cooled-down, filtered, failed, and no_actor rows. Focus first on High/Medium severity, portfolio symbols, trusted sources, and explicit mainline-aligned tickers.

psql -X -v ON_ERROR_STOP=1 -P pager=off -c "
WITH bounds AS (
  SELECT EXTRACT(EPOCH FROM now() - INTERVAL '24 hours')::BIGINT AS start_ts
)
SELECT to_char(to_timestamp(d.sent_at_ts) AT TIME ZONE 'Asia/Shanghai', 'YYYY-MM-DD HH24:MI:SS') AS logged_local,
       d.actor, d.channel, d.status, d.severity,
       e.symbols_json, e.source, e.title, e.summary, e.url
FROM delivery_log d
LEFT JOIN events e ON e.id = d.event_id, bounds
WHERE d.sent_at_ts >= bounds.start_ts
  AND (
    d.status IN ('filtered','no_actor','failed','omitted','capped','cooled_down','price_cooled_down')
    OR d.channel IN ('prefs','router','digest_item')
  )
ORDER BY d.actor, d.severity DESC, d.sent_at_ts DESC
LIMIT 200;
"

Load holdings when judging actor relevance:

ruby -rjson -e 'puts JSON.parse(File.read("data/portfolio/portfolio_telegram__direct__8039067465.json"))["holdings"].map { |h| h["symbol"] }.uniq.join(",")'

Potential misses:

  • trusted-source High/Medium news for a holding was filtered as Low/noise.
  • same-day hard signal should have upgraded a holding-related Low news item.
  • useful global macro floor was absent from a personalized digest.
  • delivery failed for channel-specific reasons after generation succeeded.
  • digest cap omitted better items while lower-value items were sent.

Output Format

Keep the final review concise and evidence-backed:

Window: 2026-05-01 00:00-24:00 Asia/Shanghai
Actors reviewed: telegram::::8039067465, ...

Summary:
- sent immediate: N
- digest batches: N
- digest items sent / omitted: N / N
- filtered / failed / no_actor: N

Findings:
1. [duplicate] actor / time / event_id / title / evidence / recommendation
2. [noise] ...
3. [should_digest] ...

Representative good pushes:
- ...

Recommended follow-up:
- code fix / baseline sample / prefs change / no action

Include exact event ids, actor ids, local send times, titles, statuses, and URLs when available. Do not overgeneralize from one sample; mark uncertain cases as "needs more samples".

Scheduled Daily Report

For the daily 10:00 review job, write one committed Markdown report for the previous Asia/Shanghai date:

docs/event-review/YYYY-MM-DD.md

The report should include:

  • exact local date window and UTC bounds;
  • actors reviewed, limited to actors with at least one valid sent/dryrun push in that local date;
  • per-actor summary counts for immediate pushes, digest batches, digest items sent/omitted, filtered/no_actor/failed rows;
  • findings grouped by duplicate, noise, bad_timing, should_filter, should_digest, and should_immediate;
  • representative good pushes so later reviewers know what "expected" looked like;
  • recommended follow-up: no action, prefs tweak, code fix, or baseline candidate.

Keep committed reports concise. Do not commit raw data/exports/event-engine-calibration/ files, private DB files, full sent bodies, or long article excerpts. If the day has no actor with valid pushes, still write a short docs/event-review/YYYY-MM-DD.md report saying so.

Escalation

If the review identifies a durable bug or baseline case:

  • Use event-engine-baseline-testing before changing event-engine code, fixtures, or LLM classifier expectations.
  • Add only durable public sample fields to baseline fixtures.
  • Keep raw daily exports ignored and out of commits.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.