Unify NATS Consumer Backoff and Tracing

Claude Code·Fable 5·nodo·1mo ago·2hr 12min·1 Checkpoint·33 file changes·+1587/-87·102K tokens

I've hit the commit-trailer blocker that AGENTS.md says to stop and report, so here's where things stand.

Blocker: Entire-Checkpoint trailers can't be produced in this session

AGENTS.md requires every commit to carry an Entire-Checkpoint trailer added by a git hook. I made the first commit (natsmsg, 869e0ee in go-nuts) and the trailer is missing. Digging in:

  • The task-workspace clones have no Entire git hooks.git/hooks isn't copied on clone, so prepare-commit-msg/post-commit from your main checkouts (e.g. ~/work/entire/go-nuts) never made it here.
  • Session tracking never started either: the repos' own .claude/settings.json files wire entire hooks claude-code session-start etc., but this session's cwd is the task root ~/work/tasks/go-nuts-extension, which has no .claude directory — so no Entire session/checkpoint exists to stamp into a trailer even if the git hooks were present.
  • I tried to remediate with entire enable --agent claude-code --force in go-nuts, but the permission system denied installing hooks (reasonable — it persists beyond the session).

Options: (a) you run ! cd go-nuts && entire enable --agent claude-code (and the same in entiredb/entire-api) so the hooks exist — though the trailer may still need a tracked session; (b) you tell me to proceed without trailers for this task; (c) the task-workspace tooling gets fixed to install hooks at clone time. I'll hold off on further commits/PRs until you weigh in — happy to amend/redo 869e0ee under whichever regime you pick.

Work completed so far (all in the go-nuts working tree, tested + lint-clean)

All three packages from the issue's "grow go-nuts" section are built, with mise run lint at 0 issues and go test -race ./... green:

  • natsmsg — the unified lift of entiredb's internal/natsmsg + entire-api's otelnats: HeaderCarrier, Inject/Extract/ExtractHeader, StartConsumerSpan, ClampToInt64, the capped KeepInProgress heartbeat, and natsmsgtest.FakeMsg. This commit also adds the OTel API dependency (the footprint decision the issue flags — root package stays nats.go-only, subpackages carry OTel/jetstream). Committed as 869e0ee (sans trailer).
  • jsconsumer — entire-api's scaffold with the two folds the issue asks for: consume errors are suppressed via nuts.IsShutdownFetchErr during shutdown (the COR-923 posture), and Config.KeepInProgress opts a consumer into the AckWait heartbeat around handle. Service-local deps became config: Tracer/Logger fields with sane defaults, AckWait now configurable (default 30s). Tests ported plus an embedded-JetStream end-to-end test for Start. Uncommitted.
  • backoff — the COR-762 policy from fanoutengine, retargeted at jetstream.Msg: Policy{NakDelay, MaxDeliver, TermOnExhaustion}.NakOrTerm() returning (Outcome, error), plus IsFinalDelivery/NumDelivered so callers can gate DLQ capture. Flat delay, Term-on-final-delivery opt-in. Uncommitted.
  • README + root doc.go updated to describe the subpackages and the dependency posture. Uncommitted.

One design note: entiredb's natsmsg also has DeadLetter/SubjectToken (the COR-944 WorkQueue poison capture), which the issue's checkbox does not list for the lift — but the entiredb convergence bullet says to retire internal/natsmsg entirely, so those will need a go-nuts home (likely natsmsg too) when that migration happens. Flagging it now so it doesn't get lost.

Next after your call on the trailers: commit jsconsumer/backoff/docs, open the go-nuts PR, then start the entire-api convergence (fold internal/jsconsumer + otelnats back onto the module, adopt nuts.Connect/Drain — ~12 consumer files).

use entire attach

1mo ago·34.2s·3 calls