Skip to content

integration/v0.13.0-rc4: x402 settle-guard, /v1 discovery fix, hermes context config, flow de-flakes, dead-code sweep#749

Merged
OisinKyne merged 13 commits into
mainfrom
integration/v0.13.0-rc4
Jul 14, 2026
Merged

integration/v0.13.0-rc4: x402 settle-guard, /v1 discovery fix, hermes context config, flow de-flakes, dead-code sweep#749
OisinKyne merged 13 commits into
mainfrom
integration/v0.13.0-rc4

Conversation

@bussyjd

@bussyjd bussyjd commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Summary

What changed: v0.13.0-rc4 integration train. Rolls up the four post-rc4 fix PRs (#743 x402 settle-guard for disconnected buyers + spec.maxConcurrentRuns, #744 flow-03 first-completion de-flake, #745 discovery /v1 api_base fix ending the poisoned-model-group 404s, #747 committee-verified dead-code sweep ~630 LOC + docs refresh) plus two integration-branch fixes found by the release smoke itself: explicit hermes model.context_length/max_tokens rendering (hermes ≥64K requirement invisible through LiteLLM) and flow-03 tool-call reasoning headroom.

Why it matters: closes the two chronic release-smoke failures (flow-11 poisoned model group, flow-03 flake), makes buyer-disconnect settlements impossible, and produces the first fully green 18-flow release smoke including the two OBOL flows (13/14) that had never passed.

Risk level: medium

Commit under test: 8f9b58e
Base branch: main

Scope

  • Code
  • Charts / manifests
  • Flows / QA scripts
  • Docs / skills

Validation

Unit tests:

go build ./... && go vet ./... && go test ./... -count=1 — all green at 8f9b58e58df56de5c886ac680415866858c40447
(go vet: pre-existing darwin-only unsafe.Pointer noise in internal/enclave excluded; present since #288)

Release smoke:

RELEASE_SMOKE_INCLUDE_OBOL=true RELEASE_SMOKE_INCLUDE_OBOL_FORK=true \
OBOL_LLM_ENDPOINT=http://127.0.0.1:8000/v1 OBOL_LLM_MODEL=qwen36-nvfp4 \
./flows/release-smoke.sh
RUN_ID: rc4-run7-20260714-171005 — result: PASS — 18/18 flows (suite numbering skips 12/15/18)

Flow tests:

Flow Network QA machine label Result
01–11, 16–21 (local suite) k3d + anvil spark1 (GB10) PASS
flow-13 dual-stack OBOL k3d fork spark1 PASS
flow-14 live OBOL base-sepolia spark1 PASS

Live Chain Evidence

Network: base-sepolia (eip155:84532)
RPC/provider: Alchemy (key redacted)
Facilitator: https://x402.gcp.obol.tech

Contracts and tokens:

Name Address Version / notes
OBOL token 0x0a09371a8b011d5110656ceBCc70603e53FD2c78 ERC-20 + Permit2 flow
USDC (base-sepolia) 0x036CbD53842c5426634e7929541eC2318f3dCF7e flow-11 settlement asset

Wallet roles:

Role Address Source
Alice / seller / register 0xC0De030F6C37f490594F93fB99e2756703c4297E flow-14 receipt summary
Bob / buyer / payer 0x57b0eF875DeB5A37301F1640E469a2129Da9490E flow-14 receipt summary

Transaction receipts:

Purpose Tx hash Status
ERC-8004 registration (agent 8092) 0x7236a592437d102b0ffa2769f0904a58ee1e74011af472d213c0104c91315e3b success
Settlement transfer (OBOL Permit2) 0x13bfa013c7dcd6b7eb0021f0bf86b361d61f3adc6a091718ef1b0d2ee58c1180 0x1
USDC settlement (flow-11) 0x1f554692bdabb9fafcaaa136400851d37672a9d3f99e317944ae8d7f48e07428 0x1

Known non-gating warning: flow-14 setMetadata reverts (custom error 0x7e273289) when metadata is already set on the live registry from a prior QA run; registration + settlement unaffected.

Runtime Evidence

Item Value
OS / arch Ubuntu arm64 (NVIDIA GB10)
Backend k3d, anvil, cloudflared tunnels
QA LLM vLLM qwen36-nvfp4 (NVFP4), max_model_len 65536, qwen3_coder tool parser + qwen3 reasoning parser
hermes-agent nousresearch/hermes-agent:v2026.7.1

Superseded PRs

Content already on main (patch-equivalent, landed via the earlier rc4 train): #726, #728, #729, #730, #731, #732, #733.
Rolled into this integration branch: #743, #744, #745, #747.
All will be closed as superseded with a reference to this PR.

Related issues: #742 (zombie settlement, fixed), #746 (model-group newtypes follow-up), #748 (dormant-capability subtree decisions — TEE/OpenClaw kept).

https://claude.ai/code/session_014YjPMViNrZ7zBVgUQzwEKk

bussyjd and others added 13 commits July 14, 2026 10:05
Renders gateway.api_server.max_concurrent_runs into the agent's
config.yaml. Nil omits the gateway block (Hermes internal default, 10);
0 disables the in-process cap so edge concurrency middleware governs
instead. Existing agents render byte-identical.

Part of #742.

Claude-Session: https://claude.ai/code/session_014YjPMViNrZ7zBVgUQzwEKk
If the buyer's request context is already canceled when the upstream
handler succeeds, do not settle — the buyer would be debited for a
response nobody receives (proven on-chain against hyperliquid-analyst,
see #742). Reports failure reason client_disconnected; the interceptor
hijacks the write path so nothing reaches the dead socket.

Fixes the propagated-cancel leg of #742.

Claude-Session: https://claude.ai/code/session_014YjPMViNrZ7zBVgUQzwEKk
The first chat completion after stack-up intermittently fails with
empty output (curl -f hides the response; observed across three
release-smoke runs while steps 3-7 through the same port-forward and
key always pass). Retry up to 3x and surface the HTTP status so a real
failure is diagnosable instead of an empty string.

Claude-Session: https://claude.ai/code/session_014YjPMViNrZ7zBVgUQzwEKk
Local-server auto-discovery registered OpenAI-compatible endpoints
(vLLM on :8000) with a bare api_base. LiteLLM's OpenAI provider does
not append /v1 (CLAUDE.md pitfall 6), so every request through the
discovered entry hit POST /chat/completions and 404'd. When an explicit
'obol model setup custom --endpoint .../v1' entry shared the same model
group, requests coin-flipped between the good and bad deployment —
root cause of the intermittent release-smoke flow-11 step[43] 404 and
the flow-03 step[2] flake (latent since v0.10.0, 69f25bf).

Claude-Session: https://claude.ai/code/session_014YjPMViNrZ7zBVgUQzwEKk
Zero callers anywhere (including tests) — flagged by the /v1 pipeline
audit's dead-code sweep alongside WarnAndStripV1Suffix (removed in
#745). Other deadcode-tool hits in internal/{buy,inference} are
test-covered exported API and were left alone.

Claude-Session: https://claude.ai/code/session_014YjPMViNrZ7zBVgUQzwEKk
…urrent-runs', 'origin/fix/flow03-first-request-retry' and 'origin/fix/discovery-api-base-v1' into integration/v0.13.0-rc4
Two-vendor (GPT + Grok) audited deletions, intersection-only:
- inference: dead ProbeEndpoint/ScanLocalEndpoints/DetectServerType/
  ParseModelsResponse wrappers (live path is the *Context variants
  used by model discovery); tests retargeted to live functions
- erc8004: superseded NewClient/Register/RegisterDetailed/SetAgentURI
  (+ETH/RegisterWithOpts/SubmitRegister); tests retargeted to the
  WithOpts variants
- x402: ResolveAssetInfo/BuildV1Requirement/TokenSupportedOnChain
  (production uses ResolveAssetInfoForPayment/BuildV2Requirement/
  ResolveToken); test coverage migrated, not dropped
- hermes: hermesExecArgs legacy test adapter + dead List/Skills/
  ResolveInstance; agentruntime/dns/stack/schemas/serviceoffercontroller
  zero-reference symbols; dead flow-lib shell functions
- flow-11: fix stale diag capture (deploy/litellm -c x402-buyer ->
  deploy/x402-buyer, stale since the b68fc34 split)

Held back by committee split or product decision: RouteRulesForOffer
(golden-test seam), erc8004 SetMetadata, all TEE/CoCo + enclave +
OpenClaw capabilities (kept intentionally, see #748).

Claude-Session: https://claude.ai/code/session_014YjPMViNrZ7zBVgUQzwEKk
- pitfall 6 generalized: EVERY LiteLLM openai/ api_base must include
  /v1 (LiteLLM posts <api_base>/chat/completions verbatim); buyer-side
  tooling uses the opposite convention; discovery fixed in #745
- new pitfall 22: poisoned model group (two deployments, one bare
  api_base -> intermittent 404, no retry; GET /model/info vs CM is
  the decisive check)
- new pitfall 23: buyer disconnect != no charge (hermes non-streaming
  path completes + settles after abort; keep runs short via
  spec.maxTurns; maxConcurrentRuns semantics; 4xx never settled)
- skill: lessons table updated (poisoned model group, parserless QA
  endpoint -> relaunch with publisher-exact launcher), version 3.2.0

Claude-Session: https://claude.ai/code/session_014YjPMViNrZ7zBVgUQzwEKk
…d agents

Hermes agents cannot discover the real context window through LiteLLM
(its /models response strips max_model_len) and fall back to assuming
65536 tokens — then request max_tokens=65536, which any backend with a
smaller window rejects. Hermes misclassifies that as context exhaustion,
compresses a near-empty conversation, and dies with "Context length
exceeded (21 tokens). Cannot compress further." — the exact failure of
flow-13/14 step 45 (agent readiness preflight), reproduced and fixed
standalone against hermes-agent v2026.7.1 + vLLM.

Hermes also hard-requires >=64K context, so the QA endpoint itself must
serve >=65536 (spark1 vLLM relaunched with --max-model-len 65536).

- generateConfig: honor OBOL_LLM_CONTEXT_LENGTH / OBOL_LLM_MAX_TOKENS
  env knobs -> model.context_length / model.max_tokens (hermes config
  resolution step 0, overrides its probing)
- release-smoke: default OBOL_LLM_CONTEXT_LENGTH=65536,
  OBOL_LLM_MAX_TOKENS=8192 whenever the OBOL flows are enabled

Claude-Session: https://claude.ai/code/session_014YjPMViNrZ7zBVgUQzwEKk
…s 100->2048)

Reasoning models (qwen3 family behind the vLLM reasoning parser) emit
reasoning_content before the tool call; at max_tokens=100 the budget is
sometimes exhausted mid-reasoning and the response comes back
finish_reason=length with no tool_calls — an intermittent FAIL on an
otherwise healthy endpoint (passed run5, failed run6, temperature=0
notwithstanding). 2048 verified live: finish_reason=stop, tool call
returned.

Claude-Session: https://claude.ai/code/session_014YjPMViNrZ7zBVgUQzwEKk

@OisinKyne OisinKyne left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like a surprising amount of deletions but i'll trust you on it

@OisinKyne
OisinKyne merged commit 2b17616 into main Jul 14, 2026
11 checks passed
@OisinKyne
OisinKyne deleted the integration/v0.13.0-rc4 branch July 14, 2026 11:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants