用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/lukemcqueen/hermes-cortex --skill webapp-deploy-verification命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
Cross-server agent health monitoring using binary status vectors — deploy health endpoints on each agent, poll from orchestrator, alert on state transitions.
Wire a self-hosted Langfuse instance to Hermes Agent — generate API keys, configure env vars, enable the bundled plugin, install SDK, and verify traces flow.
Use before enforcement code changes or shared-repo commits.
正在显示 SKILL.md
| name | webapp-deploy-verification |
| version | 1.0.0 |
| description | Verify deployed web app routes render and links resolve. |
| author | Hermes Cortex |
| metadata | {"hermes":{"tags":["web","deploy","verification","e2e","routes","links","nextjs","docker"],"related_skills":["deploy-load-verification","integration-audit","dogfood"]}} |
Git commit ≠ running deployment. A committed file is not a serving page. The only proof a web app works is exercising the URL another user would hit and observing the real response. Three axes are independently verifiable — check all three:
Enumerate the route tree from the app dir, then curl each one over the deployed path (never the dev server):
import requests
BASE = "http://127.0.0.1:PORT" # the deployed/proxied origin
routes = ["/", "/about", "/about/x", ...] # from find apps/web/src/app -name page.tsx
for r in routes:
resp = requests.get(BASE + r, allow_redirects=False, timeout=20)
# treat 3xx as "follow, then check final"; 4xx/5xx = broken
Gotchas from the field:
/admin was
layout-only → 404; same for a bare /questions where only [slug] exists).
Flag these separately — no link targets them, but they 404 on direct visit.<title> from each 200 body to confirm you got the right page, not
a generic error page that still returns 200.Read hrefs, then FOLLOW them. Reading href text alone proves nothing. The
expensive failure this session: an i18n header prepended /${locale} (= /en/)
to every nav/footer href, but the locale was a runtime preference
(localStorage/navigator), NOT a URL route — no [locale] dir, no middleware, no
i18n rewrite existed. Every nav/footer link 404'd when clicked, while:
Only following each link surfaced it. The technique:
for each route:
visit it in a real browser, collect every internal <a href>
dedupe the global link set
then HTTP-GET every unique link and assert 200
Also intersect the collected link graph against the actual route tree —
a nav pointing /warriors when the page is /warrior (or /rest vs /breath)
is a dead link neither a route crawl nor a label check will catch.
Synthetic DOM events (dispatchEvent/mouseover) do NOT trigger CSS :hover —
to verify a hover dropdown use a real pointer move, or check the menu nodes exist
in the DOM with correct hrefs and trust the CSS rule.
A compose healthcheck failing does NOT mean the service is down — it means the
probe can't reach the service. unhealthy ≠ down. See the container
pitfalls below; the two classic traps are a server bound to the container IP
(not loopback) and localhost fanning out to IPv6 [::1] first.
server.js binds
to HOSTNAME, which Docker resolves to e.g. 172.26.0.6:3000. A healthcheck
wget http://localhost:3000/ inside is refused while the published -p port
works fine from the host (DNAT targets the container IP).localhost → IPv6 [::1] first. Even after an all-interface bind, a probe
of the hostname localhost resolves to [::1] and gets refused on the
IPv4-only listener. Probe the literal http://127.0.0.1:PORT/, never the
localhost hostname.HOSTNAME: "0.0.0.0" in the compose environment: (or ENV HOSTNAME=0.0.0.0 in the runner stage) AND probe the explicit IPv4 address in
the healthcheck. Verify inside:
docker exec <c> netstat -tlnp | grep :PORT → 0.0.0.0:PORT LISTEN, then
wget -q --spider http://127.0.0.1:PORT/; echo $? → 0.scripts/webapp-http-crawl.py — ready-to-run HTTP route crawl + link check:
pass --base <url> and --routes file-or-list; reports OK/BAD per URL.<a href> collected from the live pages returns 200<title> tag present and correct on the served HTML (empty title = missing metadata export)healthy (not a false unhealthy while serving)