jobseek-error-review — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited jobseek-error-review (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.
Use this skill for the daily crawler error review. Operate from the repo state and these instructions; do not rely on prior conversation context.
Prefer running this through Codex app automation or a local Codex CLI session from the repository root. Codex app automations for Git repositories run in dedicated background worktrees, which keeps routine output isolated from active development work. This routine should use subscription-backed Codex execution where possible. Do not implement it as a scheduled API-billed Codex GitHub Action.
The legacy Claude slash command at .claude/commands/jobseek-error-review.md remains a compatibility fallback. Keep behavior equivalent when using that fallback, but treat this skill as the Codex-first runbook.
Do not spawn subagents by default. They cost extra tokens and are only useful when the current run has large independent evidence sets and the user explicitly asks for them. If subagents are used, keep them read-only and make the main agent responsible for dedupe, classification, redaction, and all GitHub write decisions.
Scan the last 24 hours of errors on the crawler Hetzner box, classify each error class against prior reviews and prior GitHub issues, write a dated Markdown report, and file or update GitHub issues only for classes that meet the filing criteria.
Model issue quality after prior examples #2622, #2621, #2470, and #2431. Never mutate remote host state. GitHub writes are allowed only when the class is novel, regressing, spiking, or an incident after dedupe.
[email protected]~/.ssh/hetzner_deploy/home/deploy/docker-compose.ymlLong-running services. Collect logs with explicit --since and --until:
deploy-worker-1-1 - HTTP workerdeploy-worker-2-1 - HTTP workerdeploy-worker-3-1 - HTTP workerdeploy-browser-1-1 - Playwright/Lightpanda workerdeploy-exporter-1 - Postgres to Supabase and Typesense CDCdeploy-drain-1 - R2 description uploaderdeploy-indexnow-1 - IndexNow notifierdeploy-redis-1 - local queue; only OOM and level=error linesdeploy-alloy-1 - log/metric shipper; only Alloy's own level=errorEphemeral one-shots are exited containers created inside the review window whose image matches ghcr.io/*/jobseek-crawler:*. Enumerate them with:
docker ps -a --filter status=exited --format '{{.Names}} {{.Image}} {{.CreatedAt}} {{.Status}}'These include crawler refresh-typesense, backfill-typesense, sync, notify-indexnow, and reconcile runs. Grab logs with docker logs <id> before exited container logs age out. Ignore interactive debug containers such as tesla-debug, stupefied_hofstadter, and goofy_haibt.
minute. Use explicit --since and --until values so log collection exactly matches the report header.
.md report under~/dev/claude/review-jobseek-errors/ before classifying. The directory name is legacy; keep using it for cross-run continuity unless a migration has already been completed.
gh issue list --label daily-error-review --state all --limit 200 \
--json number,title,state,createdAt,body gh pr list --state merged --limit 40 --json number,title,mergedAtCollect host signals before detailed log review. These commands are allowed without sudo as deploy:
df -h /
df -h /var/lib/docker
free -h
uptime
docker stats --no-stream --format 'table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}\t{{.MemPerc}}'
docker inspect --format '{{.Name}} OOMKilled={{.State.OOMKilled}} Status={{.State.Status}} RestartCount={{.RestartCount}} FinishedAt={{.State.FinishedAt}}' $(docker ps -aq)
dmesg -T 2>/dev/null | tail -n 500
journalctl -k --since "24 hours ago" --no-pager 2>/dev/null | tail -500Use journalctl -k as a fallback if dmesg is restricted. If both kernel log commands are restricted, note the gap under ## Host and do not treat that gap alone as an incident.
Flag an incident if any of these are true:
/ usage is at least 85%./var/lib/docker usage is at least 85% when it is a separate mount.RestartCount incremented since yesterday's report.Out of memory: Killed process, I/O error,EXT4-fs error, Call Trace:, or systemd OOM-killer entries.
docker ps.For each long-running service:
docker logs --since "<ISO>" --until "<ISO>" <container> 2>&1Parse structlog JSON where possible. Fall back to line matching only for non-JSON lines. Extract level, event, service_name, exception class, and a stable stack or message fingerprint.
For exited ephemeral containers inside the window:
docker logs <id> 2>&1 | tail -n 1000Attribute those errors to a synthetic service derived from the command, such as refresh-typesense or notify-indexnow.
Group errors by (service, exception class, stable message stem).
known: appears in any prior daily report within 14 days. Count it but donot file.
novel: absent from every prior report.regression: a known class that was absent for at least 3 consecutive daysand is back today.
spike: a known class whose 24-hour count is at least 3x its 7-day median.Require at least 3 prior days with non-zero signal.
incident: host-signal trigger, unexpected zero logs from a long-runningservice for more than 1 hour, data loss or corruption signal, repeated OOM kills, or exporter/drain/indexnow stall with queue depth climbing and no progress.
Always write a report, even on a healthy day.
Path:
~/dev/claude/review-jobseek-errors/YYYY-MM-DD.mdIf today's file already exists, append a ## Rerun HH:MM UTC section instead of overwriting it.
Report schema:
# Daily error review - YYYY-MM-DD
Window: YYYY-MM-DD HH:MM UTC -> YYYY-MM-DD HH:MM UTC
## Host
| metric | value |
|---|---|
## Totals
| service | info | warning | error |
|---|---:|---:|---:|
## Error classes (24h)
| class | service | count | status |
|---|---|---:|---|
## Details
## Filed issues
## HealthUnder ## Details, include every novel, regression, spike, or incident class:
Under ## Filed issues, list issue URLs filed or updated in this run, or write none.
File or update issues only for novel, regression, spike, or incident classes.
Deduplicate first:
gh issue list --label daily-error-review --state all \
--search "<error class stem or keyword>"Match by error class and service, not exact title.
first-seen, and last-seen. Do not open a duplicate.
comment explaining the recurrence.
New issue template:
## Summary
One paragraph with service, what broke, whether it is visible or silent, the
explicit 24-hour window, and suspected PR reference if any.
## Signal
5-day trend table (-4, -3, -2, -1, today) of count or batched log-line count.
Explain the unit.
## Sample log line
{"level":"error","event":"redacted sample"}
## Root cause hypothesis
1. Candidate with file-path reference only and fix direction.
2. Candidate with file-path reference only and fix direction.
## Impact
User-facing consequence such as stale data, disabled boards, or silent
failure. If invisible beyond `level=error`, say so.Title shape:
[daily-error-review] <service>.<error_stem> (<trend>; <blast>)For critical incidents, prefix the title with [critical].
Labels are required:
daily-error-reviewerror-review:critical, error-review:high,error-review:medium, or error-review:low
Severity mapping:
error-review:critical: active incident or data-loss risk.error-review:high: regression or full-service blast radius.error-review:medium: spike or partial-service regression.error-review:low: novel but contained.The repository is public. Redact before any GitHub write:
jseek.co or public CDNs./home or /root.as filename:function only.
Local reports under ~/dev/claude/review-jobseek-errors/ are private. Raw details belong there, not in GitHub issues.
Allowed on the remote box:
docker logsdocker psdocker inspectdocker stats --no-streamdffreeuptimedmesgjournalctl -k when accessible/home/deploy//tmp/ that you created this runForbidden on the remote box:
docker exec, docker kill, and any docker composesubcommand.
systemctl./tmp temporary files you created this run./tmp temporary files you created this run.sudo.Writing scripts to /tmp on the remote box is allowed only when the script is idempotent and read-only. Remove scripts after use.
If a command's effect is not completely known to be read-only, stop, write the intent to today's report, classify the gap as an incident, and do not run it.
For any incident:
daily-error-review anderror-review:critical.
[critical] at the start of a new critical issue title.~/dev/claude/review-jobseek-errors/ALERTS.md:
YYYY-MM-DD HH:MM UTC <one-sentence> <issue URL>Use this rollout when changing the routine or moving it to a new automation surface:
issue state; write the report; list would-file or would-update issues without creating, reopening, or commenting on GitHub issues.
but file only when the criteria are unambiguous and the evidence is already redacted.
report is written, known issues are deduped, no forbidden command is used, and any GitHub write is justified by the classification rules.
wording such as Claude-only phrasing, direct API billing, or obsolete command names.
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.