This specification is maintained by the AgentRules Working Group. Have enhancements or want to claim maintainership?Submit Specification →
backendcritical PriorityID: go-chi-context-aware-drain-boundary

Go Chi Context-Aware In-Flight Connection Drain Boundary

Enforces strict two-phase graceful shutdown semantics in Go Chi HTTP services operating within container orchestrators. Guarantees zero dropped in-flight requests by synchronizing OS signal interception, readiness probe failure propagation, bounded connection draining via http.Server.Shutdown, and root request context cancellation propagation to downstream resources.

Prohibited Anti-Pattern: Immediate process termination via os.Exit or unbounded http.Server.Shutdown without readiness probe de-registration or request context inheritance.

Export Ready-to-Drop Configuration

Select format below to copy code or download file directly.

---
description: Go Chi Context-Aware In-Flight Connection Drain Boundary - Enforces strict two-phase graceful shutdown semantics in Go Chi HTTP services operating within container orchestrators. Guarantees zero dropped in-flight requests by synchronizing OS signal interception, readiness probe failure propagation, bounded connection draining via http.Server.Shutdown, and root request context cancellation propagation to downstream resources.
globs: cmd/**/*.go, internal/server/**/*.go, main.go
alwaysApply: true
verified_by: "agentrules.org"
license: "CC-BY-4.0"
source: "https://agentrules.org/rules/go-chi-context-aware-drain-boundary"
---

# Go Chi Context-Aware In-Flight Connection Drain Boundary

> **Severity**: CRITICAL | **Category**: backend
> **Anti-Pattern Warning**: Immediate process termination via os.Exit or unbounded http.Server.Shutdown without readiness probe de-registration or request context inheritance.

## System Constraints
You are a Principal Backend Architect enforcing strict zero-downtime HTTP lifecycle invariants in Go services using Chi router. You must mandate deterministic signal handling (SIGTERM/SIGINT), pre-shutdown drain delays to accommodate ingress/kube-proxy iptables convergence, deterministic context-driven shutdown timeouts via http.Server.Shutdown, and strict propagation of r.Context() to all database, cache, and RPC operations executed by Chi route handlers.

## Strict Guidelines
- Engineers MUST ALWAYS isolate OS signal trapping into a buffered channel of size 1 (signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)) before starting the server.
- Engineers MUST ALWAYS run http.Server.ListenAndServe in an isolated goroutine and verify that ErrServerClosed is handled without panicking or triggering error exits.
- Engineers MUST execute a pre-drain pause (e.g., 5-15 seconds) after SIGTERM in containerized deployments to allow external ingress controllers and load balancers to remove the endpoint before http.Server.Shutdown begins rejecting new SYN packets.
- Engineers MUST ALWAYS pass a bounded timeout context (context.WithTimeout) to http.Server.Shutdown to prevent hung client connections or malicious slowloris requests from stalling container termination past the orchestrator SIGKILL deadline.
- Engineers MUST NOT spawn detached background goroutines inside Chi handlers using context.Background(); all asynchronous work spawned by a request must inherit r.Context() or be delegated to an explicit worker pool with dedicated lifecycle management.
- Services MUST mark the readiness probe as failing immediately upon receiving SIGTERM while keeping the liveness probe returning 200 OK during the entire drain duration.
- Components NEVER call os.Exit() or log.Fatal() from within HTTP handler call stacks or mid-flight shutdown routines without first closing open connection pools and draining active tasks.

## Bad vs Good Implementations
### Production-Grade Chi Server Lifecycle with Bounded Context Drain

#### Bad Antipattern (AI Common Hallucination)
> **Why it fails**: The HTTP server blocks the main thread with no SIGTERM interception. When Kubernetes sends SIGTERM, the container terminates immediately, severing in-flight connections. Furthermore, handler work is dispatched via unmonitored goroutines using no context propagation.
```go
package main

import (
	"net/http"
	"github.com/go-chi/chi/v5"
)

func main() {
	r := chi.NewRouter()
	r.Get("/work", func(w http.ResponseWriter, r *http.Request) {
		// Flaw: Spawns un-tracked background work with detached context
		go doLongWork()
		w.WriteHeader(http.StatusOK)
	})

	// Flaw: Blocking ListenAndServe with no SIGTERM trapping or Shutdown boundary
	http.ListenAndServe(":8080", r)
}

func doLongWork() {}

```

#### Production Standard (Correct)
> **Standard**: Implements an end-to-end two-phase graceful drain: (1) captures SIGTERM cleanly, (2) flips readiness check to 503 while allowing in-flight requests to proceed, (3) waits for network mesh routing table synchronization, (4) executes srv.Shutdown with an orchestrated bounded context, falling back to srv.Close() only upon deadline expiration.
```go
package main

import (
	"context"
	"errors"
	"log"
	"net/http"
	"os"
	"os/signal"
	"sync/atomic"
	"syscall"
	"time"

	"github.com/go-chi/chi/v5"
)

func main() {
	var isShuttingDown atomic.Bool
	r := chi.NewRouter()

	// Readiness probe returns 503 as soon as termination sequence begins
	r.Get("/readyz", func(w http.ResponseWriter, r *http.Request) {
		if isShuttingDown.Load() {
			http.Error(w, "Draining", http.StatusServiceUnavailable)
			return
		}
		w.WriteHeader(http.StatusOK)
	})

	r.Get("/work", func(w http.ResponseWriter, r *http.Request) {
		select {
		case <-r.Context().Done():
			http.Error(w, r.Context().Err().Error(), http.StatusRequestTimeout)
			return
		case <-time.After(2 * time.Second):
			w.WriteHeader(http.StatusOK)
		}
	})

	srv := &http.Server{
		Addr:         ":8080",
		Handler:      r,
		ReadTimeout:  5 * time.Second,
		WriteTimeout: 10 * time.Second,
		IdleTimeout:  60 * time.Second,
	}

	serverErrors := make(chan error, 1)
	go func() {
		if err := srv.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) {
			serverErrors <- err
		}
	}()

	shutdownSig := make(chan os.Signal, 1)
	signal.Notify(shutdownSig, syscall.SIGINT, syscall.SIGTERM)

	select {
	case err := <-serverErrors:
		log.Fatalf("Fatal server startup error: %v", err)
	case <-shutdownSig:
		isShuttingDown.Store(true)
		// Optional: Sleep for ingress propagation delay (e.g., 5s)
		time.Sleep(5 * time.Second)

		ctx, cancel := context.WithTimeout(context.Background(), 25*time.Second)
		defer cancel()

		if err := srv.Shutdown(ctx); err != nil {
			if errors.Is(err, context.DeadlineExceeded) {
				log.Println("Graceful shutdown deadline exceeded; forcing close")
			}
			_ = srv.Close()
		}
	}
}

```

Recommended Agent Skills (askills.dev)

Ready-to-use executable skill functions tailored to this stack.

Architectural Specification & Invariant Rationale

Architectural Invariant Design: Go Chi Context-Aware In-Flight Connection Drain Boundary

Go Chi Context-Aware In-Flight Connection Drain Boundary defines an industrial-grade behavioral standard for backend engineering. Enforces strict two-phase graceful shutdown semantics in Go Chi HTTP services operating within container orchestrators. Guarantees zero dropped in-flight requests by synchronizing OS signal interception, readiness probe failure propagation, bounded connection draining via http.Server.Shutdown, and root request context cancellation propagation to downstream resources. Modern software architectures require strict adherence to deterministic patterns to guarantee high availability, maintainability, and zero security vulnerabilities.

Framework Paradigm Shift & Drift MechanicsLLMs are trained on millions of open-source repositories containing outdated code, legacy idioms, and unpatched antipatterns. When coding assistants generate implementations for this stack, they default to common statistical tokens: Immediate process termination via os.Exit or unbounded http.Server.Shutdown without readiness probe de-registration or request context inheritance. Without an explicit system instruction file, developers spend hours debugging silent failures.
Failure Modes & Production Blast Radius

Hazard Analysis: What Breaks Without This Rule

The following failure modes have been cataloged from hundreds of hours of production code reviews where AI assistants produced non-compliant implementations:

Failure ModeAI Symptom (The Anti-Pattern)SeverityProduction Impact & Remedy
AI Hallucination & Deprecation DriftImmediate process termination via os.Exit or unbounded http.Server.Shutdown without readiness probe de-registration or request context inheritance.Critical
Violating this industrial standard introduces regression bugs, security risks, and unexpected runtime failures in production.
Enforce explicit behavioral system directives across all AI coding assistants in your repository.
Silent Architecture InconsistencyAI assistants produce mixed paradigms across files, creating fragmented codebase conventions.Medium
Increases cognitive load during code reviews and leads to maintenance debt across engineering teams.
Pin project conventions in .cursor/rules, CLAUDE.md, and AGENTS.md so all team agents follow identical guardrails.
Architectural Directives in Detail

Step-by-Step Production Directives

Each rule constraint below is injected into the AI agent's system prompt to establish deterministic boundaries:

1

Engineers MUST ALWAYS isolate OS signal trapping into a buffered channel of size 1 (signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)) before starting the server.

Engineers MUST ALWAYS isolate OS signal trapping into a buffered channel of size 1 (signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)) before starting the server.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
2

Engineers MUST ALWAYS run http.Server.ListenAndServe in an isolated goroutine and verify that ErrServerClosed is handled without panicking or triggering error exits.

Engineers MUST ALWAYS run http.Server.ListenAndServe in an isolated goroutine and verify that ErrServerClosed is handled without panicking or triggering error exits.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
3

Engineers MUST execute a pre-drain pause (e.g., 5-15 seconds) after SIGTERM in containerized deployments to allow external ingress controllers and load balancers to remove the endpoint before http.Server.Shutdown begins rejecting new SYN packets.

Engineers MUST execute a pre-drain pause (e.g., 5-15 seconds) after SIGTERM in containerized deployments to allow external ingress controllers and load balancers to remove the endpoint before http.Server.Shutdown begins rejecting new SYN packets.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
4

Engineers MUST ALWAYS pass a bounded timeout context (context.WithTimeout) to http.Server.Shutdown to prevent hung client connections or malicious slowloris requests from stalling container termination past the orchestrator SIGKILL deadline.

Engineers MUST ALWAYS pass a bounded timeout context (context.WithTimeout) to http.Server.Shutdown to prevent hung client connections or malicious slowloris requests from stalling container termination past the orchestrator SIGKILL deadline.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
5

Engineers MUST NOT spawn detached background goroutines inside Chi handlers using context.Background()

Engineers MUST NOT spawn detached background goroutines inside Chi handlers using context.Background(); all asynchronous work spawned by a request must inherit r.Context() or be delegated to an explicit worker pool with dedicated lifecycle management.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
6

Services MUST mark the readiness probe as failing immediately upon receiving SIGTERM while keeping the liveness probe returning 200 OK during the entire drain duration.

Services MUST mark the readiness probe as failing immediately upon receiving SIGTERM while keeping the liveness probe returning 200 OK during the entire drain duration.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
7

Components NEVER call os.Exit() or log.Fatal() from within HTTP handler call stacks or mid-flight shutdown routines without first closing open connection pools and draining active tasks.

Components NEVER call os.Exit() or log.Fatal() from within HTTP handler call stacks or mid-flight shutdown routines without first closing open connection pools and draining active tasks.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
Technical Questions & Answers

Frequently Asked Technical Questions

Common questions developers face when configuring AI coding assistants for this stack:

Q:Why is Go Chi Context-Aware In-Flight Connection Drain Boundary critical for AI coding assistants?

Enforces strict two-phase graceful shutdown semantics in Go Chi HTTP services operating within container orchestrators. Guarantees zero dropped in-flight requests by synchronizing OS signal interception, readiness probe failure propagation, bounded connection draining via http.Server.Shutdown, and root request context cancellation propagation to downstream resources. Without explicit behavioral boundaries, AI coding assistants (Cursor, Claude Code, Windsurf, Codex) rely on training data averages, which frequently produce deprecated, inefficient, or vulnerable code patterns.

Q:How does adopting this rule prevent AI hallucinations?

This rule explicitly declares what the AI must avoid (Immediate process termination via os.Exit or unbounded http.Server.Shutdown without readiness probe de-registration or request context inheritance.) and prescribes verified positive examples. Grounding the LLM with negative and positive pairs eliminates guesswork.

Q:Which AI coding environments are supported?

This specification is multi-platform compatible: Cursor (.cursor/rules/*.mdc & .cursorrules), Anthropic Claude Code (CLAUDE.md), Windsurf (.windsurfrules), Codex / Cline (AGENTS.md), and GitHub Copilot (.github/copilot-instructions.md).

Q:Can I combine this rule with other technology stacks?

Yes. Use the Interactive Stack Builder or download an Agent Pack to merge this rule with other frontend, backend, database, security, and DevOps rules without syntax collision.

Open Specification · CC BY 4.0·Free for Personal, Team & Commercial In-Repo Use

Citation & Open Source Attribution Guidelines

This specification is licensed under Creative Commons Attribution 4.0 International (CC BY 4.0). You are completely free to adapt and share this rule in your workspace. If citing, including in public AI benchmark datasets, or redistributing, attribution to AgentRules.org is required.

1 Rule in Stack

Go