{
  "id": "go-service",
  "name": "Go service: net/http + PostgreSQL + sqlc + River",
  "use_cases": [
    "APIs",
    "control planes",
    "concurrent network services",
    "background workers"
  ],
  "choose_when": [
    "Prefer explicit service code and standard tooling",
    "Kubernetes or Go infrastructure integration matters",
    "PostgreSQL already owns business state"
  ],
  "avoid_when": [
    "Need a batteries-included product framework",
    "Hard real-time or no-GC constraints",
    "Rich client UI is the primary product"
  ],
  "tools": [
    {
      "job": "HTTP server",
      "default": "net/http",
      "alternatives": [
        "Existing project router when justified"
      ],
      "reason": "Standard handlers and request contexts minimize routing infrastructure.",
      "limits": "Set request/body limits, deadlines and graceful shutdown; middleware and authorization remain application work.",
      "source_urls": [
        "https://pkg.go.dev/net/http"
      ]
    },
    {
      "job": "Optional server-rendered UI",
      "default": "templ + HTMX",
      "alternatives": [
        "No UI for API-only services"
      ],
      "reason": "Compiled components and HTML-fragment updates suit forms and dashboards.",
      "limits": "Generation adds a build step; advanced client state still needs browser-side design and testing.",
      "source_urls": [
        "https://templ.guide/",
        "https://htmx.org/docs/"
      ]
    },
    {
      "job": "Database and migrations",
      "default": "PostgreSQL + pgx + sqlc + goose",
      "alternatives": [
        "pgx without sqlc for small query sets",
        "golang-migrate when already established"
      ],
      "reason": "Visible SQL, generated typed access and one migration owner.",
      "limits": "Generators do not prove query efficiency; review transaction boundaries, pool budgets and online migration behavior. Never mix migration owners.",
      "source_urls": [
        "https://github.com/jackc/pgx",
        "https://docs.sqlc.dev/en/latest/",
        "https://github.com/pressly/goose",
        "https://github.com/golang-migrate/migrate"
      ]
    },
    {
      "job": "Configuration",
      "default": "Typed settings loaded with os.LookupEnv",
      "alternatives": [
        "flag for small command surfaces"
      ],
      "reason": "Explicit startup validation and standard structured logs.",
      "limits": "Define precedence; reject malformed required values; redact secrets. Environment access alone is not validation or secret management.",
      "source_urls": [
        "https://pkg.go.dev/os",
        "https://pkg.go.dev/flag",
        "https://pkg.go.dev/log/slog"
      ]
    },
    {
      "job": "Application logging",
      "default": "log/slog",
      "alternatives": [],
      "reason": "Explicit startup validation and standard structured logs.",
      "limits": "Define precedence; reject malformed required values; redact secrets. Environment access alone is not validation or secret management.",
      "source_urls": [
        "https://pkg.go.dev/os",
        "https://pkg.go.dev/flag",
        "https://pkg.go.dev/log/slog"
      ]
    },
    {
      "job": "Tests and static checks",
      "default": "testing; go vet; race detector; govulncheck",
      "alternatives": [],
      "reason": "Standard toolchain feedback plus exercised concurrency and known-vulnerability checks.",
      "limits": "Race detector requires supported target/toolchain and exercised code; no scanner proves absence of vulnerabilities.",
      "source_urls": [
        "https://pkg.go.dev/testing",
        "https://go.dev/doc/articles/race_detector",
        "https://golangci-lint.run/docs/welcome/quick-start/",
        "https://go.dev/doc/security/vuln/"
      ]
    },
    {
      "job": "HTTP and database integration tests",
      "default": "httptest + real disposable PostgreSQL",
      "alternatives": [
        "In-process handler tests for pure routing"
      ],
      "reason": "Exercise protocols and actual SQL/migrations.",
      "limits": "Database tests need an isolated database; mocks cannot establish PostgreSQL semantics.",
      "source_urls": [
        "https://pkg.go.dev/net/http/httptest",
        "https://github.com/jackc/pgx"
      ]
    },
    {
      "job": "Durable work",
      "default": "River for PostgreSQL-backed jobs",
      "alternatives": [
        "Temporal Go SDK for workflow requirements needing its service"
      ],
      "reason": "Transactional enqueueing ties work to committed business data.",
      "limits": "External effects need idempotency. Default resumable checkpoints may be lost on crash; use transactional checkpoints where required. Inspect Pro feature boundaries.",
      "source_urls": [
        "https://riverqueue.com/docs/transactional-enqueueing",
        "https://riverqueue.com/docs/resumable-jobs",
        "https://docs.temporal.io/develop/go"
      ]
    },
    {
      "job": "Deployment and distribution",
      "default": "Go build binary in a supervised process or container; GoReleaser for releases",
      "alternatives": [],
      "reason": "Small explicit runtime boundary; release automation builds target artifacts.",
      "limits": "Target OS/architecture, libc/cgo, CA certificates, timezone data and signing need explicit verification. Snapshot builds are not publication.",
      "source_urls": [
        "https://goreleaser.com/getting-started/quick-start/"
      ]
    },
    {
      "job": "Browser identity",
      "default": "go-oidc + existing OIDC provider",
      "alternatives": [
        "Preserve an existing compatible project choice"
      ],
      "reason": "Provider discovery and ID-token verification support owned login sessions",
      "limits": "Use v3 module; configure issuer/client, OAuth callback state and session lifecycle. go-oidc verifies ID tokens; API access-token validation follows the provider contract. Authorization stays near data.",
      "source_urls": [
        "https://github.com/coreos/go-oidc"
      ]
    },
    {
      "job": "Transactional email",
      "default": "go-mail + project-selected SMTP provider",
      "alternatives": [
        "Preserve an existing compatible project choice"
      ],
      "reason": "Typed mail construction and SMTP transport support application messages",
      "limits": "Configure TLS, sender credentials and timeouts; send required mail through durable jobs with duplicate protection. Validate chosen async/runtime features in Rust; delivery receipts and bounces need provider handling.",
      "source_urls": [
        "https://pkg.go.dev/github.com/wneessen/go-mail"
      ]
    },
    {
      "job": "Uploads and object storage",
      "default": "AWS SDK for Go S3 client",
      "alternatives": [
        "Preserve an existing compatible project choice"
      ],
      "reason": "Durable object storage avoids dependence on service-local disk",
      "limits": "Configure runtime credentials, region and least-privilege bucket access; authorize object keys and uploads, bound size/concurrency and define retention. Test multipart cleanup and selected provider compatibility.",
      "source_urls": [
        "https://docs.aws.amazon.com/sdk-for-go/v2/developer-guide/go_s3_code_examples.html"
      ]
    },
    {
      "job": "Realtime transport",
      "default": "coder/websocket",
      "alternatives": [
        "Server-sent events for one-way feeds",
        "Polling for infrequent updates"
      ],
      "reason": "WebSocket support fits bidirectional connected clients",
      "limits": "Enable the documented module/feature; authorize handshake and every protected message, bound queues/message size and implement heartbeat/shutdown. Socket delivery is not durable history; define reconnect/resync.",
      "source_urls": [
        "https://pkg.go.dev/github.com/coder/websocket"
      ]
    }
  ],
  "setup_steps": [
    "Start in a new source checkout in a local development workspace; run go mod init example.com/project using the real module path.",
    "Resolve and record Go/tool versions and dependencies; go get github.com/jackc/pgx/v5; add River only if jobs are needed.",
    "Create cmd/server plus application packages, typed settings, explicit http.Server limits, health/readiness and shutdown handling.",
    "Install selected sqlc and goose releases; write migrations and sqlc configuration; run sqlc generate. Configure a disposable PostgreSQL database through environment/secrets.",
    "With GOOSE_DRIVER=postgres and GOOSE_DBSTRING targeting only the disposable database, run goose -dir migrations up. Add business transaction and River enqueue tests.",
    "Add the chosen release configuration, pin tools and preserve go.mod/go.sum; document build and rollback. These steps have not been run."
  ],
  "verification_commands": [
    "gofmt -l .",
    "go test ./...",
    "go test -race ./...",
    "go vet ./...",
    "govulncheck ./...",
    "sqlc generate",
    "goose -dir migrations status",
    "go build ./cmd/server"
  ],
  "evidence_status": "documentation-reviewed",
  "sources": [
    {
      "url": "https://pkg.go.dev/net/http",
      "title": "Go net/http",
      "checked_date": "2026-10-10"
    },
    {
      "url": "https://templ.guide/",
      "title": "templ",
      "checked_date": "2026-10-10"
    },
    {
      "url": "https://htmx.org/docs/",
      "title": "HTMX",
      "checked_date": "2026-10-10"
    },
    {
      "url": "https://github.com/jackc/pgx",
      "title": "pgx PostgreSQL driver",
      "checked_date": "2026-10-10"
    },
    {
      "url": "https://docs.sqlc.dev/en/latest/",
      "title": "sqlc documentation",
      "checked_date": "2026-10-10"
    },
    {
      "url": "https://github.com/pressly/goose",
      "title": "goose migrations",
      "checked_date": "2026-10-10"
    },
    {
      "url": "https://github.com/golang-migrate/migrate",
      "title": "golang-migrate",
      "checked_date": "2026-10-10"
    },
    {
      "url": "https://pkg.go.dev/os",
      "title": "Go os configuration primitives",
      "checked_date": "2026-10-10"
    },
    {
      "url": "https://pkg.go.dev/flag",
      "title": "Go flag",
      "checked_date": "2026-10-10"
    },
    {
      "url": "https://pkg.go.dev/log/slog",
      "title": "Go structured logging",
      "checked_date": "2026-10-10"
    },
    {
      "url": "https://pkg.go.dev/testing",
      "title": "Go testing",
      "checked_date": "2026-10-10"
    },
    {
      "url": "https://go.dev/doc/articles/race_detector",
      "title": "Go data race detector",
      "checked_date": "2026-10-10"
    },
    {
      "url": "https://golangci-lint.run/docs/welcome/quick-start/",
      "title": "golangci-lint quick start",
      "checked_date": "2026-10-10"
    },
    {
      "url": "https://go.dev/doc/security/vuln/",
      "title": "Go vulnerability management",
      "checked_date": "2026-10-10"
    },
    {
      "url": "https://pkg.go.dev/net/http/httptest",
      "title": "Go HTTP testing",
      "checked_date": "2026-10-10"
    },
    {
      "url": "https://riverqueue.com/docs/transactional-enqueueing",
      "title": "River transactional enqueueing",
      "checked_date": "2026-10-10"
    },
    {
      "url": "https://riverqueue.com/docs/resumable-jobs",
      "title": "River resumable jobs",
      "checked_date": "2026-10-10"
    },
    {
      "url": "https://docs.temporal.io/develop/go",
      "title": "Temporal Go SDK",
      "checked_date": "2026-10-10"
    },
    {
      "url": "https://goreleaser.com/getting-started/quick-start/",
      "title": "GoReleaser quick start",
      "checked_date": "2026-10-10"
    },
    {
      "url": "https://github.com/coreos/go-oidc",
      "title": "go-oidc repository",
      "checked_date": "2026-10-10"
    },
    {
      "url": "https://pkg.go.dev/github.com/wneessen/go-mail",
      "title": "go-mail documentation",
      "checked_date": "2026-10-10"
    },
    {
      "url": "https://docs.aws.amazon.com/sdk-for-go/v2/developer-guide/go_s3_code_examples.html",
      "title": "AWS Go S3 examples",
      "checked_date": "2026-10-10"
    },
    {
      "url": "https://pkg.go.dev/github.com/coder/websocket",
      "title": "coder/websocket documentation",
      "checked_date": "2026-10-10"
    }
  ],
  "open_questions": [
    "Which API contracts, browser login or service-token requirements apply?",
    "Does realtime need one-way updates or bidirectional sockets?",
    "Which database pool, worker throughput, storage and deployment/restore budgets apply?"
  ],
  "title": "Go service",
  "language": "Go",
  "group": "APIs & services",
  "kind": [
    "api"
  ],
  "ui": "none",
  "host": "binary",
  "summary": "HTTP APIs and backend services with a straightforward binary deployment.",
  "shape": "net/http · pgx · sqlc · PostgreSQL",
  "tradeoff": "Product features such as authorization and administration need explicit assembly.",
  "research_file": "go-rust.json",
  "reviewed": "2026-10-10",
  "best_practices": [
    "Propagate contexts and set timeouts on external requests. Bound concurrency and handle shutdown.",
    "Keep SQL and migrations reviewed and generated query code synchronized with the schema.",
    "Test handlers with httptest and persistence against a disposable real PostgreSQL instance.",
    "Use River only when durable jobs are required; test retry-safe effects and worker shutdown."
  ],
  "research_freshness": {
    "core_guidance_checked_on": "2026-10-13",
    "sources": [
      "https://go.dev/doc/tutorial/create-module",
      "https://pkg.go.dev/net/http"
    ],
    "scope": "Core framework roles, current setup/agent documentation and cited-source availability rechecked; not a reimplementation or exhaustive semantic audit of every third-party dependency."
  },
  "guide_url": "/stacks/go-service/",
  "markdown_url": "/stacks/go-service/guide.md",
  "json_url": "/stacks/go-service/record.json",
  "architecture_and_migration": {
    "id": "go-service",
    "version_scope": "Go 1.27 release documentation and current net/http/context APIs; sqlc latest transaction guide with pgx/v5; River current documentation, PostgreSQL composition. Resolve and record Go toolchain, sqlc, pgx and River versions in go.mod/go.sum and tool configuration before implementation. Official release notes identify Go 1.27 as the August 2026 release; this research does not qualify a lockfile or patch-version/security support.",
    "operating_model": "Recommendation: a Go HTTP process owns request admission and cancellation, domain packages own invariants, and a bounded SQL connection pool provides parallel database access. Durable jobs have their own persisted queue and worker lifecycle. Goroutines and buffered channels are concurrency mechanisms; graceful drain does not turn them into a recoverable queue.",
    "architecture": [
      "Recommendation: compose net/http handlers around small domain packages and explicit interfaces at external boundaries. Pass request contexts into SQL and outbound calls. Use bounded errgroup fan-out or a worker pool, with an overload policy separate from concurrency limits.",
      "Recommendation: maintain reviewed SQL migrations and sqlc-generated queries; share a pool, acquire transactions only around domain writes, and call generated WithTx for the transaction. A single global mutex around all queries recreates avoidable serialization.",
      "Recommendation: PostgreSQL-backed River workers can run with the web binary initially or in an independent process when their scaling or shutdown needs differ. Insert business state and a job in the same database transaction when atomic enqueue is required; cross-database work needs a separately designed outbox.",
      "Recommendation: retain an established identity provider, object store, email sender and broker during a service rewrite. Request/response, cookies, WebSocket application protocol, job payload and retry semantics are separate compatibility contracts."
    ],
    "developer_workflow": [
      "Recommendation: start from the existing repository; inspect go.mod, go.sum, schema migrations and queue configuration. For a new local source project, go mod init example.com/service creates a module; choose the actual module path and supported toolchain deliberately.",
      "Recommendation: pin sqlc using the maintained tool installer, review sqlc.yaml and SQL source, then run sqlc generate after query/schema changes. Regenerate in CI and compare output; generated typing does not validate production schema drift.",
      "Recommendation: run gofmt on changed files, go vet ./..., go test ./... and go test -race ./... on a supported target. Add HTTP contract fixtures and cancellation/queue crash tests against the selected database; these are proposed checks, not executed here.",
      "Recommendation: build the service with go build ./cmd/server when that entry point exists. Set server/header/body deadlines, worker limits, pool capacity and shutdown budget from the deployment shape. Profile a representative workload with Go pprof; performance and cost remain unmeasured."
    ],
    "avoid": [
      "Avoid one fire-and-forget goroutine per email/payment: an acknowledged request can survive while its side effect disappears on process crash.",
      "Avoid spawning unlimited goroutines to hide slow SQL. The downstream pool becomes the queue; cancellation, memory and overload must be bounded explicitly.",
      "Avoid replacing Redis solely because Go has channels. Shared fan-out, sessions, queue persistence and locks have different semantics.",
      "Avoid treating Server.Shutdown as complete WebSocket shutdown; hijacked connections need separate notification and tracking."
    ],
    "transitions": [
      {
        "capability": "data",
        "existing_contract": "Inventory the old schema, isolation, identifiers, null handling, timestamps and transaction invariants before changing language or driver.",
        "coexistence": "Recommendation: let the old application own migrations while Go accesses backward-compatible columns through sqlc; route writes for one domain/cohort to one owner. Expand schema before either runtime needs it.",
        "target": "Recommendation: sqlc plus pgx/v5 or database/sql, a shared bounded pool and explicit transaction-scoped queries. Keep the existing database if its guarantees fit; PostgreSQL replacement is a separate migration.",
        "benefits": [
          {
            "benefit": "Typed query access and concurrent pool usage can improve maintainability and remove an unnecessary application-wide lock.",
            "prerequisites": "Queries generated from the reviewed schema; representative null/time/transaction fixtures; a pool sized across all replicas.",
            "tradeoffs": "Generated types do not prove isolation or business correctness; pool exhaustion and migrations still need operations."
          }
        ],
        "checks": [
          "Verify old-write/new-read and new-write/old-read round trips, including nulls and time zones.",
          "Force a mid-transaction failure; neither half of the domain change may commit.",
          "Saturate the pool and cancel a request; verify bounded waiting and connection release."
        ],
        "rollback": "Recommendation: return domain traffic to the old writer while preserving expanded columns. Contract migrations wait until the rollback window closes; reconcile any new-only writes first.",
        "sources": [
          "https://docs.sqlc.dev/en/latest/howto/transactions.html",
          "https://go.dev/doc/database/manage-connections"
        ],
        "id": "data-1"
      },
      {
        "capability": "jobs",
        "existing_contract": "Capture existing queue kind, JSON arguments, retry/schedule/dead-letter states and external-effect idempotency. Redis/Resque or Sidekiq payloads are not River payloads.",
        "coexistence": "Recommendation: keep old workers consuming old queues. Route selected job kinds into River through versioned producers; transform outstanding states explicitly and retain one scheduler. River Ruby integration is a possible bridge, not automatic Active Job execution.",
        "target": "Recommendation: River PostgreSQL jobs with domain writes plus InsertTx in the same transaction, explicit queue concurrency and bounded retry policy. Keep Redis for any remaining broker/session/cache responsibility.",
        "benefits": [
          {
            "benefit": "Atomic enqueue closes the gap between committing domain state and creating work.",
            "prerequisites": "Domain rows and River insertion use the same transaction/database; validated job-kind/argument mapping; replay-safe external effects.",
            "tradeoffs": "Adds queue schema/maintenance to the database; retries can repeat effects; backlog migration and adapter compatibility are separate work."
          }
        ],
        "checks": [
          "Abort the domain transaction; no job may become available.",
          "Crash after sending an email but before job completion; retry must reconcile or reuse a stable external idempotency key.",
          "Account for ready, scheduled, retry, failed and in-flight jobs before retiring the old consumer."
        ],
        "rollback": "Recommendation: stop new River producers and reroute only unstarted work after reconciliation. Keep a compatible River consumer for already accepted jobs; a broker switch cannot undo sent messages or payments.",
        "sources": [
          "https://riverqueue.com/docs/transactional-enqueueing",
          "https://riverqueue.com/docs/job-retries",
          "https://riverqueue.com/docs/ruby"
        ],
        "id": "jobs-1"
      },
      {
        "capability": "operations",
        "existing_contract": "Preserve response/error behavior, overload rules, deadlines and restart guarantees; establish separate budgets for HTTP and background jobs.",
        "coexistence": "Recommendation: serve a fixed tenant/endpoint cohort from Go behind existing routing, with errgroup/context cancellation inside each operation and deployment-level readiness. Keep the old instance ready for contract-compatible rollback.",
        "target": "Recommendation: signal.NotifyContext, bounded admission/fan-out, Server.Shutdown with a fresh timeout context, tracked worker termination and pool closure after accepted work ends.",
        "benefits": [
          {
            "benefit": "Cooperative cancellation limits work that callers no longer need and makes planned shutdown observable.",
            "prerequisites": "Every called operation honors context; in-flight tasks are tracked; the platform shutdown grace period exceeds the configured drain budget.",
            "tradeoffs": "Cancellation does not reverse a committed write or external effect; forced termination still loses memory-only work."
          }
        ],
        "checks": [
          "Cancel a client while SQL/outbound I/O is blocked; verify resources and goroutines settle.",
          "Send SIGTERM during a write; the server stops admitting traffic and records whether accepted work committed.",
          "Force SIGKILL; verify durable jobs recover independently of graceful drain."
        ],
        "rollback": "Recommendation: return routing to the old process and inspect committed outcomes and queued work before any replay. Preserve identical database/schema contracts for both versions.",
        "sources": [
          "https://pkg.go.dev/net/http#Server.Shutdown",
          "https://pkg.go.dev/golang.org/x/sync/errgroup",
          "https://pkg.go.dev/os/signal#NotifyContext"
        ],
        "id": "operations-1"
      },
      {
        "capability": "realtime",
        "existing_contract": "Preserve authentication, subscription identifiers, frame formats, ordering, reconnect cursors and cross-runtime fan-out. A WebSocket transport does not implement Action Cable automatically.",
        "coexistence": "Recommendation: keep the existing broker and explicit application-protocol adapter while moving complete room/tenant cohorts, including reconnects, to Go. Publish/subscribe in both directions using captured protocol fixtures.",
        "target": "Recommendation: coder/websocket for transport plus bounded per-connection queues, tracked close handshakes and an application resynchronization path. Retain Redis Pub/Sub if ephemeral cross-process fan-out fits; add durable history separately where missed events matter.",
        "benefits": [
          {
            "benefit": "Explicit connection ownership and queue limits bound slow-client resource use.",
            "prerequisites": "Capacity and disconnect policy are defined; clients can reconnect and reconstruct authoritative state; broker/protocol compatibility is tested.",
            "tradeoffs": "Redis Pub/Sub is at-most-once and does not replay disconnected messages; replacing it with process-local channels removes cross-instance delivery."
          }
        ],
        "checks": [
          "Connect an old and new client to the same room; verify broadcasts in both directions and revocation.",
          "Disconnect a subscriber and publish; reconnect must fetch missed authoritative state.",
          "Throttle one client; verify the configured queue overflow policy and independent delivery to others."
        ],
        "rollback": "Recommendation: route the cohort and reconnects back together. Keep the broker and old protocol alive; rebuild client state from durable records rather than pretending ephemeral events can be replayed.",
        "sources": [
          "https://github.com/coder/websocket",
          "https://redis.io/docs/latest/develop/pubsub/",
          "https://pkg.go.dev/net/http#Server.Shutdown"
        ],
        "id": "realtime-1"
      }
    ],
    "sources": [
      {
        "url": "https://go.dev/doc/go1.27",
        "title": "Go 1.27 release notes",
        "claim": "Identifies the August 2026 release; runtime/tool behavior and JSON v2 are documented with compatibility caveats."
      },
      {
        "url": "https://go.dev/doc/modules/managing-dependencies",
        "title": "Managing Go dependencies",
        "claim": "go.mod and go.sum own module dependency versions."
      },
      {
        "url": "https://docs.sqlc.dev/en/latest/howto/transactions.html",
        "title": "sqlc transactions",
        "claim": "Generated WithTx binds queries to a transaction; pgx/v5 example is documented."
      },
      {
        "url": "https://go.dev/doc/database/manage-connections",
        "title": "Go SQL connection management",
        "claim": "sql.DB is a concurrent pool; limits can cause waits and deadlocks."
      },
      {
        "url": "https://riverqueue.com/docs/transactional-enqueueing",
        "title": "River transactional enqueue",
        "claim": "Enqueue with domain changes in one transaction avoids a two-store commit gap."
      },
      {
        "url": "https://riverqueue.com/docs/job-retries",
        "title": "River retries",
        "claim": "Retry attempts and delays are configurable; errors lead to repeated execution."
      },
      {
        "url": "https://riverqueue.com/docs/ruby",
        "title": "River Ruby integration",
        "claim": "Current documentation describes a shared River schema and explicit job kinds/JSON arguments."
      },
      {
        "url": "https://pkg.go.dev/net/http#Server.Shutdown",
        "title": "net/http server shutdown",
        "claim": "HTTP drain does not close or await hijacked WebSocket connections."
      },
      {
        "url": "https://pkg.go.dev/golang.org/x/sync/errgroup",
        "title": "errgroup",
        "claim": "WithContext cancellation and SetLimit support bounded concurrent work."
      },
      {
        "url": "https://pkg.go.dev/os/signal#NotifyContext",
        "title": "os/signal",
        "claim": "NotifyContext connects OS signals to context cancellation."
      },
      {
        "url": "https://github.com/coder/websocket",
        "title": "coder/websocket README",
        "claim": "Go WebSocket transport supports contexts and close handshakes; application protocol is separate."
      },
      {
        "url": "https://redis.io/docs/latest/develop/pubsub/",
        "title": "Redis Pub/Sub",
        "claim": "Pub/Sub delivery is at-most-once; disconnected subscribers miss events."
      }
    ],
    "reviewed_at": "2026-10-11",
    "evidence": "documentation-reviewed"
  },
  "rewrite_url": "/rewrite/guide.md",
  "migration_contracts_url": "/rewrite/contracts.json",
  "agent_workflow": [
    "Read README, dependency manifests, lockfiles, runtime pins and the maintained project workflow before changing anything. Preserve an existing stack unless reconsidering it is part of the request.",
    "Use this guide to select tools by requirement. Resolve compatible versions from official and installed-version documentation; record the actual lockfile and runtime versions.",
    "Create a plan for schema changes, identity, authorization, external effects and deployment. A library choice does not complete its integration.",
    "Run relevant checks after configuration. Exercise the real interface, failure paths and packaged artifact on the intended target. Report commands, versions, results and untested behavior.",
    "On failure, retain the command and diagnostic, fix the failing prerequisite and resume there. Do not regenerate over existing work or suppress failures to make a check green."
  ],
  "selection": {
    "native_ui": false,
    "static_hosting": false,
    "offline_client_candidate": false
  },
  "coverage_note": "Tools are curated starting points for this application role. Exact versions, integrations and offline behavior require project-specific qualification."
}
