analyzing-options
Analyzing different approaches for a task or problem with structured comparisons, effort…
Adopting the lib-commons/v5 shared Huma (OAS 3.1) OpenAPI wrapper + RFC 9457 problem model (commons/net/http/{openapi,problem}) in a Lerian Go service: wire openapi.New/ServeSpec + problem.Install (central >=500 scrub) on BOTH runtime and spec-gen paths, the per-rail
$ npx -y skills add LerianStudio/ring --skill adopting-lib-commons-huma-wrapper --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/adopting-lib-commons-huma-wrapperContext preview
The summary Claude sees to decide when to auto-load this skill.
Adopting the lib-commons/v5 shared Huma (OAS 3.1) OpenAPI wrapper + RFC 9457 problem model (commons/net/http/{openapi,problem}) in a Lerian Go service: wire openapi.New/ServeSpec + problem.Install (central >=500 scrub) on BOTH runtime and spec-gen paths, the per-rail
name: ring:adopting-lib-commons-huma-wrapper
description: "Adopting the lib-commons/v5 shared Huma (OAS 3.1) OpenAPI wrapper + RFC 9457 problem model (commons/net/http/{openapi,problem}) in a Lerian Go service: wire openapi.New/ServeSpec + problem.Install (central >=500 scrub) on BOTH runtime and spec-gen paths, the per-rail problem.MapError flex seam, and rename-only spec regen. Orchestrates a gated cycle dispatching ring:backend-go. Use for greenfield Huma or migrating a service off a local openapi/humaerr wrapper. Skip for non-Go or non-HTTP work."You orchestrate. Agents implement. NEVER use Edit/Write/Bash on Go source files — all code changes go through `Task(subagent_type="ring:backend-go")`. TDD mandatory for implementation gates (RED → GREEN → REFACTOR). The orchestrator owns git (commit/push/PR/release) and NEVER commits without the user's go-ahead.
The wrapper is **two packages** in `lib-commons/v5` (minimum **v5.6.0**):
| Alias | Import Path | Purpose | |-------|-------------|---------| | `openapi` | `github.com/LerianStudio/lib-commons/v5/commons/net/http/openapi` | `Config`, `New` (builds the `humafiber` API), `DeclareBearerAuth`, `ServeSpec` | | `problem` | `github.com/LerianStudio/lib-commons/v5/commons/net/http/problem` | `Install` (global `huma.NewError` override), `MapError`, `Detail`, `BaseURI` |
**`openapi.New(app, group, cfg)`** constructs the Fiber-v2 Huma API via `humafiber.NewV2WithGroup` (the default `humafiber.New` targets Fiber v3 — wrong major), strips Transformers/OnAddOperation/CreateHooks, and **clears the auto-mounted `/openapi.json` + `/docs`** (auto-mount is a latent production exposure — the spec must be served explicitly and gated). `Config{Title, Version, Description, Servers}`.
**`openapi.ServeSpec(app, api, logger, prefix, title)`** mounts `{prefix}/openapi.json`, `{prefix}/openapi.yaml`, `{prefix}/docs` (Scalar UI). It normalizes `prefix` (leading slash, no trailing) and HTML-escapes the docs-page title and spec URL. **Gate this behind the service's `Swagger.Enabled`** flag — never serve unconditionally.
**`openapi.DeclareBearerAuth(api)`** registers the `BearerAuth` security scheme *component* (`components.securitySchemes`) so `Security` references resolve — it does NOT attach the requirement to anything. **The scheme component alone advertises ZERO secured operations.** To make the spec say "auth required" you MUST also attach a requirement, one of:
`DeclareBearerAuth` without a requirement is the classic regression: a JWT-enforced API whose spec advertises every endpoint as public. **Public endpoints** (no auth middleware at runtime) must override the global default with an explicit empty requirement: `Security: []map[string][]string{}` on the operation — a *non-nil empty slice*, which Huma renders as `security: []` because `Operation.Security` marshals with `omitNil` (Go `json:"...,omitempty"` would drop it and silently re-inherit the global default). Getting this wrong makes the spec lie about which routes need a token — see also the constraint-as-validation caveat under Dependency facts.
**`problem.Install()`** is the crux. It is a `sync.Once` override of the process-global `huma.NewError`, so EVERY error Huma builds — domain errors via `MapError` and the framework's own validation/404/422 errors — becomes a `*problem.Detail`. Merge semantics:
**`problem.MapError(err, codeOf, statusOf, fallbackCode)`** is the per-rail **flex seam** — the one place each service injects its own taxonomy:
**`problem.Detail`** embeds `huma.ErrorModel` + an `omitempty` `Code`. Services that never set a code emit a bare RFC 9457 body; coded errors mapped through `MapError` carry the machine code in `Code` + a flat `Type` URI (`BaseURI + "/" + code`). `Type` is set **only** on the `MapError` coded path — framework-built errors (native 422/404 via `Install`) keep `Type` at `about:blank` with empty `Code`.
Proven engineering practices, enforced through skills. Ring is a comprehensive skills library and workflow system for AI agents that transforms how AI assistants approach software development.
Repo: LerianStudio/ring
Analyzing different approaches for a task or problem with structured comparisons, effort…
Auditing a service's production readiness against Ring engineering standards across base…
Cleaning redundant and obvious comments following clean code principles while preserving…
Commit changes with scope allowlist enforcement, atomic grouping, GPG-signed conventional…
Creating a handoff document that captures session state (completed work, decisions, open…
Creating an isolated git worktree for parallel branch work: selects the directory by priority…