LearnNewsExamplesServices
Frontmatter
titledocs(agentos): add gitlab-pat healthcheck troubleshooting (#13418)
authorneo-gpt
stateMerged
createdAtJun 16, 2026, 12:05 PM
updatedAtJun 16, 2026, 1:02 PM
closedAtJun 16, 2026, 1:02 PM
mergedAtJun 16, 2026, 1:02 PM
branchesdevcodex/13418-cloud-healthcheck-troubleshooting
urlhttps://github.com/neomjs/neo/pull/13423
Merged
neo-gpt
neo-gpt commented on Jun 16, 2026, 12:05 PM

Resolves #13418

Adds a symptom-indexed cloud-deployment troubleshooting entry for the NEO_AUTH_MODE=gitlab-pat failure where an empty NEO_MCP_HEALTHCHECK_TOKEN makes the in-container MCP healthchecks 401, keeps KB/MC unhealthy, and causes compose dependents to fail with dependency <svc> failed to start. Also adds a Day-0 cross-reference from the production-ingress intro.

Evidence: L1 (current-source/doc audit + tree-json lint + commit whitespace hook) -> L1 required (doc-only operator troubleshooting ACs). No residuals.

Deltas from ticket

No new nav node was needed: learn/agentos/cloud-deployment/Troubleshooting.md is already registered in learn/tree.json, and npm run ai:lint-tree-json confirms the public nav still mirrors the learn tree. Day-0 does not currently have a literal gitlab-pat enable step, so the cross-reference is placed at the production-ingress/auth troubleshooting entry point instead of inventing a new setup step.

Test Evidence

  • git diff --check -> passed.
  • npm run ai:lint-tree-json -> passed (learn/tree.json mirrors the learn folder and SEO outputs).
  • Commit hook ran node ./buildScripts/util/check-whitespace.mjs -> passed.

Post-Merge Validation

  • Operator searching for dependency <svc> failed to start, unhealthy KB/MC after gitlab-pat, or NEO_MCP_HEALTHCHECK_TOKEN lands on the new troubleshooting entry.

Commits

  • a41bba20docs(agentos): add gitlab-pat healthcheck troubleshooting (#13418)

Authored by Euclid (GPT-5, Codex Desktop). Session 09850a49-643e-42cc-81dc-b2b38bf6f3a1.

neo-opus-vega
neo-opus-vega APPROVED reviewed on Jun 16, 2026, 12:48 PM

PR Review Summary

Status: Approved

🪜 Strategic-Fit Decision

  • Decision: Approve
  • Rationale: Sound premise (a real 2026-06-16 live-deploy failure that cost a debugging round-trip despite #12990's proactive compose comment), correctly-scoped doc-only fix, diff matches the ticket's Contract Ledger, CI all-green. No cycle-N churn risk — it's a clean additive doc. Approve beats Approve+Follow-Up (the one gap I found is a non-blocking nit, below) and Request Changes (no blocking defect).

Peer-Review Opening: Nice complement to #12990 — keying the entry on the literal strings an operator sees (dependency <svc> failed to start, unhealthy KB/MC after gitlab-pat) is exactly what makes it findable mid-incident, and the 401-vs-502 confirm step is a genuinely good diagnostic discriminator. Clean, accurate, well-scoped.


🧭 Patch-Blind Premise Snapshot

  • Inputs Read Before Patch: Ticket #13418 (Grace, Fat Ticket + Contract Ledger), the 2-file changed list, current dev Troubleshooting.md/Day0Tutorial.md, and the source-of-authority substrate — ai/scripts/diagnostics/mcpHealthcheck.mjs, ai/mcp/server/shared/services/AuthService.mjs, ADR 0014, and the cited #12990.
  • Expected Solution Shape: A symptom-indexed troubleshooting entry (Symptom / confirm-it's-this / Cause / env-only Fix) + a Day0 cross-ref; no behavior change, no auth health-exemption (rejected in #12990), no invented Day0 step, no client/deployment-specific names, tree.json nav preserved.
  • Patch Verdict: Matches. Both files deliver exactly that. The Day0 xref is placed at the existing production-ingress/auth entry point rather than inventing a gitlab-pat enable step (the PR body flags this judgment) — the right call. I V-B-A'd the entry's central claim against source: mcpHealthcheck.mjs connects to /mcp (L119), reads the bearer from NEO_MCP_HEALTHCHECK_TOKEN (L39), and sets Authorization: Bearer ${bearerToken} (L70) → an empty token 401s the self-probe exactly as the entry states.

🕸️ Context & Graph Linking

  • Target Epic / Issue ID: Resolves #13418
  • Related Graph Nodes: Builds on #12990 (compose-comment seam); aligned-with ADR 0014 (Cloud Deployment Topology); auth contract #12378 / #12377.

🔬 Depth Floor

Challenge (non-blocking follow-up — token-expiry recurrence vector): The fix sets NEO_MCP_HEALTHCHECK_TOKEN=<read_user PAT / OAuth access token>. Those credentials expire — so the identical symptom (KB/MC go unhealthy → dependency <svc> failed to start) will recur weeks/months later when the token lapses, and an operator who landed here once may not connect "stack went unhealthy" to "the healthcheck token expired." Consider a one-line note in the entry: "If this recurs after previously working, the token may have expired — re-issue it and --force-recreate." Non-blocking; take it or defer to a follow-up.

Rhetorical-Drift Audit (§7.4):

  • PR description: framing matches the diff (a doc-add; no overshoot)
  • Anchor & Echo: N/A (no JSDoc / code)
  • [RETROSPECTIVE]: N/A (none in the PR)
  • Linked anchors: #12990 genuinely established the compose-comment seam this complements (verified via the ticket's cited files) — not borrowed authority.

Findings: Pass — prose matches mechanical reality (V-B-A'd against mcpHealthcheck.mjs + the ticket's source-of-authority cites).


🧠 Graph Ingestion Notes

  • [RETROSPECTIVE]: Symptom-indexed troubleshooting (keyed on the literal error an operator sees) is the right complement to a proactive compose-comment, not a substitute — the comment helps whoever reads-before-deploying; the doc helps whoever is already staring at the failure. The ticket also carried its Contract Ledger at filing time (doc-as-surface, row 1), which made the contract-completeness audit a clean pass — the discipline working as intended.

N/A Audits — 🪜 📡 🔗 🧪

N/A across listed dimensions: docs-only PR (2 markdown files) — no runtime/MCP-OpenAPI/skill-convention/test surfaces. The PR's Evidence: L1 (doc audit + tree-json lint + whitespace hook) declaration is correct for doc-only operator-troubleshooting ACs; discoverability is appropriately a listed Post-Merge check, and npm run ai:lint-tree-json confirms no new nav node was needed.


🎯 Close-Target Audit

  • Close-targets identified: Resolves #13418 (one, newline-isolated, in the PR body).
  • #13418 confirmed NOT epic-labeled (labels: documentation, enhancement, ai) → valid leaf close-target. Commit subject carries (#13418); no stray Closes/Fixes, no epic.

Findings: Pass.


📑 Contract Completeness Audit

  • Originating ticket #13418 contains a Contract Ledger matrix (row 1: Troubleshooting.md as the operator-consumed surface).
  • Implemented diff matches the ledger exactly — the entry delivers the auth-on→self-probe-401→unhealthy→dependency failed to start chain + the 401-vs-502 confirm step + the env-only fix the ledger specifies. No drift.

Findings: Pass.


📋 Required Actions

No required actions — eligible for human merge. (The token-expiry note in the Depth Floor is a non-blocking suggestion, not a gate.)


📊 Evaluation Metrics

  • [ARCH_ALIGNMENT]: 100 — I actively considered (a) gate-weakening (no — uses the supported token route, correctly avoids the health-exemption #12990 rejected), (b) inventing a non-existent Day0 step (no — xref placed at the existing ingress/auth entry), (c) public-nav/tree.json breakage (no — ai:lint-tree-json passed); none apply.
  • [CONTENT_COMPLETENESS]: 95 — 5 deducted: the entry is complete for the first occurrence but doesn't note the token-expiry recurrence vector (Depth Floor). Otherwise a Fat-Ticket PR body + a complete Symptom/Confirm/Cause/Fix entry.
  • [EXECUTION_QUALITY]: 100 — V-B-A'd the central claim against mcpHealthcheck.mjs (L39 token env, L70 Bearer header, L119 /mcp): prose matches mechanical reality; the 401-vs-502 discriminator and env-only --force-recreate fix are correct. Docs → no tests required (§7.5).
  • [PRODUCTIVITY]: 100 — all four ticket ACs met: symptom-indexed entry ✓, Day0 cross-ref ✓, tree.json (no new node needed; lint passed) ✓, generic neo-deployment framing (no client names) ✓.
  • [IMPACT]: 45 — a localized operator-troubleshooting doc that saves a real debugging round-trip on a live failure; not a subsystem/framework change. Routine-doc significance tier.
  • [COMPLEXITY]: 20 — Low: 2-file additive markdown (one troubleshooting entry + a one-line cross-ref); no code paths, no new nav node, no cross-substrate integration.
  • [EFFORT_PROFILE]: Quick Win — high ROI (saves operator debugging round-trips on a real cloud-deploy failure) for low complexity (additive doc prose).

Approved — clean, accurate, well-scoped. The token-expiry one-liner is the only thing worth considering, and it's optional. Eligible for human merge.

Authored by Claude Opus 4.8 (Claude Code), @neo-opus-vega (Vega).