From 1a0e413132cd49040bd519bfb92ee989fd12fd48 Mon Sep 17 00:00:00 2001 From: Manas Srivastava Date: Sat, 6 Jun 2026 11:14:48 +0530 Subject: [PATCH] docs(llms): surface deploy-failure auto-debug path + CI discoverability guard MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Closes the agent-discoverability half of the failure-diagnosis CI program: an agent that hits a failed deploy must be able to find, from llms.txt alone, that the classified cause is served back over HTTP — and that can't silently regress. - public/llms.txt: synced to content-repo HEAD (PR #27, a10699f) — adds the "Debugging a failed deploy (agent self-recovery)" section + the /docs/troubleshooting-deploys.md reference (the /events autopsy loop: reason + last_lines + hint → fix → redeploy → re-poll). - src/lib/llmsContract.test.ts: new CONTRACT_MARKERS row asserting llms.txt contains BOTH the 'troubleshooting-deploys' reference AND the '/api/v1/deployments/:id/events' debug surface — so a content sync or docs edit that drops the debug path reds CI (verified: removing the events marker fails the test by name). - scripts/fetch-content.mjs: adds the same two markers to the llms.txt requireMarkers lock-step guard — a future upstream sync missing them PRESERVES the committed copy instead of reverting the documentation (rule 22). Pairs with the FUNCTIONAL live proof in e2e/live-ui-failure-diag.spec.ts (#195): discoverable AND demonstrably working. Co-Authored-By: Claude Opus 4.8 --- public/llms.txt | 13 ++++++++++++- scripts/fetch-content.mjs | 18 +++++++++++++++++- src/lib/llmsContract.test.ts | 16 ++++++++++++++++ 3 files changed, 45 insertions(+), 2 deletions(-) diff --git a/public/llms.txt b/public/llms.txt index e55bf6b..0419658 100644 --- a/public/llms.txt +++ b/public/llms.txt @@ -123,7 +123,8 @@ Every page has a `.md` mirror at the same path. Examples: - [/pricing.md](https://instanode.dev/pricing.md) — tier comparison - [/for-agents.md](https://instanode.dev/for-agents.md) — agent-specific guidance - [/status.md](https://instanode.dev/status.md) — current status -- [/docs.md](https://instanode.dev/docs.md) — quickstart + service reference (all 9 sections concatenated) +- [/docs.md](https://instanode.dev/docs.md) — quickstart + service reference (all sections concatenated) +- [/docs/troubleshooting-deploys.md](https://instanode.dev/docs/troubleshooting-deploys.md) — agent self-recovery guide for a failed deploy (the `/events` autopsy loop) - [/blog.md](https://instanode.dev/blog.md) — blog index (post titles + dates + links) - [/blog/.md](https://instanode.dev/blog/) — every post - [/use-cases.md](https://instanode.dev/use-cases.md) — catalogue index (all 104 grouped by category) @@ -162,6 +163,16 @@ Anonymous tier (24h TTL): no email on file, `DELETE` returns 200 immediately. Se - [Deployments](https://instanode.dev/docs#deploy): POST /deploy/new + private deploys + custom domains + two-step email-confirmed deletion + 24h-TTL semantics (default; three routes to keep a deploy permanent) +## Debugging a failed deploy (agent self-recovery) + +Deploy failed? You don't need cluster access — the platform classifies the failure and serves the real error back over HTTP. Read the classified cause at `GET /api/v1/deployments/:id/events` → `events[]` with `reason`, `last_lines` (the tail of the build-pod log = the actual error output), and `hint` (a plain-language remedy). For the one-line summary use `GET /api/v1/deployments/:id` → `status` + `error_message`. The loop: read `reason` + `last_lines` + `hint` → fix the Dockerfile / tarball / `port` / `env_vars` → redeploy in place (`POST /deploy/:id/redeploy`, or `redeploy=true` on `POST /deploy/new` with the same `name`) → re-poll status until `running`. Watch the build live with the SSE stream `GET /deploy/:id/logs`. + +**Anonymous deploys** go through `POST /stacks/new` and have a thinner failure path: `GET /api/v1/stacks/:slug` returns `status="failed"` + the raw error string, and `GET /stacks/:slug/logs/:svc` returns per-service build logs — but there is **no** classified `/events` autopsy for anonymous stacks (a known thinner path). Claim/upgrade and deploy via `/deploy/new` for the full `reason`/`last_lines`/`hint` surface. + +**Caveats:** don't rely on the failure email (transactional email delivery is currently blocked — use `/events` and the dashboard failure-autopsy panel instead); there is a brief "diagnostics pending" window right after a failure where `/events` may be empty or `reason="Unknown"` (re-poll); and runtime crash-loops have thinner diagnostics today than build failures. + +Full guide: [https://instanode.dev/docs#troubleshooting-deploys](https://instanode.dev/docs#troubleshooting-deploys) (markdown mirror: [/docs/troubleshooting-deploys.md](https://instanode.dev/docs/troubleshooting-deploys.md)). + ## How to use this file If you're an LLM helping a user build something, you can: diff --git a/scripts/fetch-content.mjs b/scripts/fetch-content.mjs index d6f315e..3faef3d 100644 --- a/scripts/fetch-content.mjs +++ b/scripts/fetch-content.mjs @@ -80,7 +80,23 @@ const SYNC_FILES = [ // version missing the Enterprise line; this PRESERVES the committed local // copy until content HEAD also carries it. Becomes a no-op once the // content PR merges. - requireMarkers: ['redeploy=true', '"redeployed":', 'not yet a self-serve tier', '**Enterprise**'], + // + // task #69 (2026-06-06): 'troubleshooting-deploys' + the dedicated debug + // surface '/api/v1/deployments/:id/events' guard agent-discoverability of the + // deploy-failure auto-debug path. An upstream sync that ever drops the + // troubleshooting reference or the events surface from llms.txt PRESERVES the + // committed copy instead of silently reverting the documentation — so an agent + // reading the live https://instanode.dev/llms.txt can always find the + // failure-diagnosis loop. Mirrors the CONTRACT_MARKERS row in + // src/lib/llmsContract.test.ts (content PR #27 already carries both, no-op today). + requireMarkers: [ + 'redeploy=true', + '"redeployed":', + 'not yet a self-serve tier', + '**Enterprise**', + 'troubleshooting-deploys', + '/api/v1/deployments/:id/events', + ], }, ] diff --git a/src/lib/llmsContract.test.ts b/src/lib/llmsContract.test.ts index cb32393..1018df4 100644 --- a/src/lib/llmsContract.test.ts +++ b/src/lib/llmsContract.test.ts @@ -81,6 +81,22 @@ const CONTRACT_MARKERS: DocsMarker[] = [ file: 'public/llms.txt', mustContain: ['**Enterprise**', 'sales@instanode.dev'], }, + { + // Task #69 / docs/ci/02-FAILURE-DIAGNOSIS-AND-AUTODEBUG.md (2026-06-06): the + // agent-facing deploy-failure auto-debug path. An agent that hits a failed + // deploy must be able to DISCOVER, from llms.txt alone, that the classified + // cause is served back over HTTP — so this pins BOTH the troubleshooting + // reference (the dedicated guide) AND the dedicated debug surface + // `GET /api/v1/deployments/:id/events` (the reliable machine surface the + // auto-debug loop reads: reason + last_lines + hint). If a content-repo sync + // or a docs edit ever drops the debug path from the manifest, this reds CI so + // agent-discoverability of the failure-diagnosis path can't silently regress. + // Mirrors the requireMarkers guard in scripts/fetch-content.mjs (lock-step, + // rule 22) + the FUNCTIONAL live proof in e2e/live-ui-failure-diag.spec.ts. + field: 'deploy-failure auto-debug path (troubleshooting guide + /events debug surface)', + file: 'public/llms.txt', + mustContain: ['troubleshooting-deploys', '/api/v1/deployments/:id/events'], + }, ] describe('agent docs contract — POST /deploy/new redeploy=true', () => {