Imported from kamedev4-rgb/OCI-Hermes-Agent (
profiles/mycare/skills/diagnostics/daily_check/SKILL.md). Install upstream withnpx skills add kamedev4-rgb/OCI-Hermes-Agent --skill daily_check. Copyright stays with the author.
MyKNOT / MyCARE Daily Check
Purpose
Run a read-only daily health check for the MyKNOT environment and produce a concise ops report.
Constraints:
- Read-only only unless an approval token explicitly authorizes writes.
- Do not modify
SOUL.md. - Do not connect to MyKNOT directly; inspect via PostgreSQL, Docker, systemd, logs, HTTP, and local config.
When to use
Use this when a cron job or user asks for:
MyCARE 定時診断MyKNOT の健全性確認- daily health / maintenance report for MyKNOT or MyCARE
Core findings this workflow is designed to catch
- Discord gateway looks healthy even when web serving is broken.
hermes --profile myknot ...may fail withProfile 'myknot' does not existeven while the real gateway is running.- The reliable workaround is to inspect the running process and reuse its
HERMES_HOME, typically:HERMES_HOME=/home/ubuntu/.hermes/profiles/myknot
- Caddy on port 80 may return the default
Caddy works!page, which means the host is up but MyKNOT is not being served. - Legacy/broken systemd units (
hermes-myknot.service,hermes-gateway.service) may remain failed while the real unit ishermes-gateway-myknot.service.
Daily check procedure
Run these checks in order.
1) Host baseline
Use terminal:
uname -a
date -Is
uptime
Record time, host, and rough load.
2) Container status
docker ps --format 'table {{.Names}}\t{{.Image}}\t{{.Status}}\t{{.Ports}}'
Expected minimum:
myknot_postgresrunning- possibly
portainer
3) Service / process state
Check failed units and relevant services:
systemctl --failed --no-pager || true
systemctl --user list-units --type=service --all --no-pager 'hermes*'
systemctl --user status hermes-gateway-myknot.service --no-pager || true
systemctl --user status hermes-gateway-mycare.service --no-pager || true
ps -ef | grep -E 'hermes|caddy' | grep -v grep
Interpretation:
hermes-gateway-myknot.serviceactive = Discord-side MyKNOT likely alivehermes-myknot.service not-found failed= stale/broken old unit, report as drift- if
systemctl --user list-unit-files 'hermes*'and filesystem checks show nohermes-myknot.service, but plainsystemctl status hermes-myknot.servicestill showsLoaded: not-found+Active: failed, treat it as a system-level failed-state residue, not an active user unit - cleanup for that residue is
sudo systemctl reset-failed hermes-myknot.service;systemctl --user reset-failed hermes-myknot.servicewill fail withUnit ... not loaded hermes-gateway.servicemay still be the active MyCARE runtime whenHERMES_HOME=/home/ubuntu/.hermes-mycare; treat this as naming drift, not automatically a failure- if both
hermes-gateway.serviceandhermes-gateway-mycare.serviceare enabled/running (or restarting together), check for Discord token conflict and report MyCARE service duplication/drift hermes-gateway.service failedwithout an active replacement = report as drift/problem
4) Discover runtime HERMES_HOME
Do this if hermes --profile myknot ... fails or if you want grounded runtime state.
Inspect the running MyKNOT PID environment:
python3 - <<'PY'
import os
pid = <MYKNOT_PID>
with open(f'/proc/{pid}/environ','rb') as f:
for item in f.read().split(b'\0'):
if item.startswith(b'HERMES_HOME='):
print(item.decode())
PY
Then use that exact path when calling Hermes CLI:
HERMES_HOME=/home/ubuntu/.hermes/profiles/myknot hermes status
HERMES_HOME=/home/ubuntu/.hermes/profiles/myknot hermes doctor
Important:
hermes --profile myknot statuscan be false-negative.- Prefer runtime
HERMES_HOMEover profile-discovery assumptions.
5) HTTP surface check
curl -fsS -o /tmp/myknot_root.out -D - http://127.0.0.1/
head -c 300 /tmp/myknot_root.out
read /etc/caddy/Caddyfile
Interpretation:
HTTP 200+ body containsCaddy works!=> web surface is wrong / degraded unless MyKNOT is intentionally Discord-first and HTTP is explicitly unusedHTTP 200+ body containsMyKNOT SaaS Server is runningwith a Caddyfilerespondrule => host-level MyKNOT liveness page is configured; treat as HTTP surface healthy for the daily check unless a full web UI/API is known to be required- Caddyfile showing only
root * /usr/share/caddyandfile_server=> default site, not MyKNOT
6) Database health
docker exec myknot_postgres pg_isready -U myknot -d myknot
docker exec myknot_postgres psql -U myknot -d myknot -Atc "select schemaname||'.'||tablename from pg_tables where schemaname='public' order by tablename;"
docker exec myknot_postgres psql -U myknot -d myknot -P pager=off -c "select id,title,severity,status,created_at,closed_at from incidents order by created_at desc limit 10;"
docker exec myknot_postgres psql -U myknot -d myknot -P pager=off -c "select key, value, updated_at from system_state order by updated_at desc limit 20;"
Expected tables commonly seen:
approval_tokensincidentsmem0migrationsmemoriessystem_state
Report:
- whether DB accepts connections
- incident count / recent incidents
maintenance_mode
7) Discord log health
Search the MyKNOT logs for current or recent Discord connection state:
search in /home/ubuntu/.hermes/profiles/myknot/logs for:
- `Connected as`
- `Disconnected`
- `ERROR`
- `Non-retryable`
- today's date
High-value signals:
Connected as MyKNOT#3032- fresh
RESUMED sessionlines on today's date = Discord websocket is still alive even if there has been no user traffic - recent inbound and response-ready lines = bot is actually serving traffic; if none exist today, report that only connection continuity was verified and active response handling was not exercised
Discord bot token already in use= duplicate gateway conflict- auth
401or quota/rate-limit429= model/provider auth or quota issue affecting replies
If broad log search output is truncated, re-read targeted ranges around the latest Connected as / RESUMED / inbound lines with read_file, and inspect errors.log for today's date before concluding the current state. For very large logs, use execute_code or a local Python one-liner to summarize only the last relevant hits from agent.log and errors.log (patterns: today's date, Connected as, RESUMED session, Disconnected, inbound message, response ready, ERROR, 401, 429, Discord bot token already in use) instead of dumping full files into context.
If today's log only shows RESUMED session continuity and no inbound/response-ready lines, classify Discord connectivity as healthy when the service is active and the current PID has an established Discord socket, but explicitly report that active response handling was not exercised today.
8) Cron / config drift check
HERMES_HOME=/home/ubuntu/.hermes/profiles/myknot hermes cron list || true
Also run/read:
HERMES_HOME=/home/ubuntu/.hermes/profiles/myknot hermes doctor || true
Treat doctor findings as drift/risk, not necessarily outage. Examples:
- missing Mem0 API key while
memory.provider: mem0is configured => memory subsystem risk/config drift - npm vulnerability reports in optional tools => maintenance risk
- missing optional provider keys/tool dependencies => capability limitation unless the affected tool is required for core MyKNOT operation
Also inspect:
/home/ubuntu/.hermes/profiles/myknot/config.yaml/home/ubuntu/.hermes/profiles/mycare/config.yaml
Useful config fields:
- MyKNOT Discord allowed/home channel
- MyCARE Discord home channel
Reporting rubric
Use one of these top-level statuses, and report them in bilingual form:
HEALTHY(正常): Discord runtime, DB, and HTTP surface all correct; no notable driftDEGRADED(一部劣化): core bot works, but web surface or config/service drift is broken/misalignedFAILED(障害): Discord runtime down, DB unavailable, or no viable service path
For this environment, prefer format C for ops reports:
- natural-language summary of the current state
- explicit judgment basis: say what you inspected and why it supports the judgment
- short bullet-style key points at the end
Recommended report structure:
- timestamp
- overall status in bilingual form
- natural-language summary
- judgment basis (
what was checked+what it showed+how that maps to the status) - Discord/runtime status
- database status
- HTTP/Caddy status
- service/profile drift
- priority risks
- short key-points line
Example key-points line:
要点: Discord正常 / DB正常 / Web不整合 / 総合判定 DEGRADED(一部劣化)
Current known-good interpretation pattern
If you observe all of the following:
hermes-gateway-myknot.serviceactive- MyKNOT Discord logs show recent
Connected asand recent inbound/response activity - PostgreSQL healthy
- HTTP root returns
Caddy works! - stale failed units still exist
hermes --profile myknot ...fails butHERMES_HOME=... hermes statusworks
Then classify as one of these, depending on intended architecture:
If HTTP/Web is intended to serve MyKNOT
- DEGRADED
- Reason:
- bot runtime is alive
- database is alive
- external web surface is misconfigured
- operational configuration drift remains unresolved
If MyKNOT is intentionally Discord-first and has no required web UI/API
- Do not automatically treat
Caddy works!as an outage or core degradation. - Report it as:
HEALTHY(正常)if Discord runtime + DB are healthy and no other meaningful drift exists, orDEGRADED(一部劣化)only if separate real drift remains (for example stale systemd units or actual token conflicts).
- Reason:
- default Caddy content may simply indicate an unused host-level web service, not a broken MyKNOT surface.
- judge HTTP findings against intended product topology, not against a generic assumption that every deployment must expose a web UI.
Restart / drain-timeout interpretation
Be careful when diagnosing an apparent Discord outage immediately after a reload or restart.
Observed pattern:
- logs may show
Gateway drain timed out after 60.0s - then
Disconnected - the old PID may remain referenced in prior checks
- systemd may later record
status=75/TEMPFAIL - because the unit has
Restart=on-failureandRestartSec=30, MyKNOT may auto-restart and reconnect a short time later
Required verification before classifying as FAILED:
- Re-check
systemctl --user show hermes-gateway-myknot.service -p MainPID,ActiveState,SubState,Result - Confirm the current PID still exists (
ps -p <MainPID>) - Inspect
journalctl --user -u hermes-gateway-myknot.service --since '<recent time>' - Re-read the tail of
agent.logfor a freshConnected as MyKNOT#3032 - Optionally confirm live socket state for the current PID (
ss -tpn | grep <MainPID>)
Classification guidance:
- If the service is disconnected and no restart/reconnect has happened after these checks, classify FAILED.
- If systemd has already restarted the unit and fresh
Connected asis present, classify the Discord runtime as recovered and do not report an active outage. - Distinguish
active (running)from actual Discord connectivity; require fresh log evidence.
Pitfalls
- Do not conclude health from
HTTP 200alone; inspect the body. - Do not conclude MyKNOT is down just because
hermes --profile myknotfails. - Do not rely only on
systemctl --failed; user-level systemd may still be serving the real gateway. - Do not write fixes during daily check unless explicitly authorized by approval token.