Skip to content

integration: v0.14.0-rc0#756

Open
bussyjd wants to merge 18 commits into
mainfrom
integration/v0.14.0-rc0
Open

integration: v0.14.0-rc0#756
bussyjd wants to merge 18 commits into
mainfrom
integration/v0.14.0-rc0

Conversation

@bussyjd

@bussyjd bussyjd commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

Summary

Integration branch for v0.14.0-rc0, collapsing open PRs #753#755 onto main:

PR Title Role
#753 chore(storefront): page-surface naming cleanup + template convention Controller/render rename + embedded offer landing template
#754 fix(hermes): edge-redirect dashboard root to password-login Dashboard HTTPRoute //auth/password-login; operator guidance
#755 docs: align install quickstart with v0.13.0 product behavior Hosts resume, OBOL_NONINTERACTIVE, dormant tunnel, obol.stack:8080 Host header

Also resolves a README merge conflict between #754 and #755 (keeps both dashboard login details and install accuracy).

Review notes

Excluded (still open, not in “#753 and above”): #750, #751, #752.

Smoke (spark1)

  • Host: spark1
  • Branch HEAD: 919502e1
  • Worktree: obol-stack-qa-20260715-212834-v014rc0-919502e1
  • Command: RELEASE_SMOKE_INCLUDE_OBOL=true RELEASE_SMOKE_INCLUDE_OBOL_FORK=true bash flows/release-smoke.sh
  • LLM: http://127.0.0.1:8000/v1 model qwen36-nvfp4
  • Result: PASS (__RELEASE_SMOKE_DONE_RC__=0, FAIL count 0, PASS count 18)
Flow Result
flow-01-prerequisites PASS
flow-02-stack-init-up PASS
flow-03-inference PASS
flow-04-agent PASS (dashboard root/login ok: root=302 final=200)
flow-05-network PASS
flow-06-sell-setup PASS
flow-07-sell-verify PASS
flow-10-anvil-facilitator PASS
flow-08-buy PASS
flow-09-lifecycle PASS
flow-16-sell-agent PASS
flow-17-sell-mcp PASS
flow-19-sell-auth PASS
flow-20-async-job PASS
flow-21-route-surface PASS
flow-11-dual-stack PASS
flow-14-live-obol-base-sepolia PASS
flow-13-dual-stack-obol PASS

Report: $QA/.tmp/release-smoke-20260715-212850/RELEASE_REPORT.md

Test plan

  • Local unit tests: go test ./internal/hermes/ ./internal/serviceoffercontroller/
  • Full release-smoke on spark1 including live OBOL + fork
  • CI green on this integration PR
  • Merge train after review; tag v0.14.0-rc0 on main when ready

bussyjd added 8 commits July 15, 2026 17:19
skillCatalog* named a busybox httpd after the first file it ever held.
It now serves skill.md, services.json (the storefront's own backend via
SERVICES_URL), openapi.json, the API docs, and one bundle per
hostname-bound offer -- including every offer landing page. "Skill
catalog" described one of those.

Two concepts were sharing the name, so this splits them:

  skillCatalog*          -> staticSite*      (the httpd + its ConfigMap)
  buildSkillCatalogMarkdown -> buildSkillMarkdown   (builds skill.md)
  skillCatalog{HowToPay,TryIt,RouteLines} -> skillMarkdown*  (its sections)
  catalogMu              -> staticSiteMu     (guards the static-site reconcile)

Identifiers only. Every k8s wire name is untouched -- obol-skill-md,
obol-skill-md-route, obol-catalog-headers and namespace x402 are all
byte-identical, verified by diffing the string literals removed against
those re-added (net zero). Renaming the objects would be a live-cluster
migration and they are referenced from internal/tunnel, cmd/obol,
internal/stackbackup, the embedded x402.yaml and next.config.ts; a
comment at the const block now explains the deliberate mismatch.

ServiceCatalog* (the /api/services.json wire types) keeps its name -- that
one is genuinely a catalog.

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

The landing page was a backtick literal buried mid-offerbundle.go while all
three x402 pages (payment_required, siwx_challenge, error_page) follow one
convention: templates/<name>.html + //go:embed + <name>HTMLSrc + <name>Tmpl.
It is the surface users actually hit and it was the only one you could not
open as HTML.

Adopts the existing x402 convention rather than inventing a second one:

  internal/serviceoffercontroller/templates/offer_landing.html
  //go:embed templates/offer_landing.html
  var offerLandingHTMLSrc string

Content is byte-identical to the previous literal (verified by extracting
the literal from origin/main and diffing against the new file), so the
rendered page is unchanged.

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

DESIGN.md told the next engineer to hand-mirror the token palette across
three files and gave a drift check to enforce it. Both were stale:
payment_required.html contains zero hex values -- theming moved to
storefront.ResolveTheme(...).CSSVars() via {{.Branding.ThemeCSS}}. The
documented check diffed hex out of that template against globals.css, so
its left side was empty and it compared an empty set forever. Following
the doc would have re-introduced exactly the drift it existed to prevent.

- SS 2: describes the real source (theme.go is the single owner) and says
  not to paste hex back in.
- SS 5: points at the one hand-mirror that does survive -- theme.ts's
  LIGHT_THEME_VARS, a fallback that rots silently because a healthy page
  takes tokens from the feed. The new check compares theme.go's ThemeLight
  against it; verified it passes today (13 pairs each side) and verified it
  FAILS on injected drift, which the old one could not do.
- SS 0: adds the five public surfaces and their data-obol="page-*" markers.
  Nothing else in the repo lists them. Records the two things that are easy
  to get backwards: page-402 renders only on a paid path with Accept:
  text/html (so a root-priced offer's browser visitors get page-landing,
  never page-402), and data-obol="checkout" is a mount div on two pages
  rather than a name for the 402 page.
- Corrects "four surfaces" -> five.

Claude-Session: https://claude.ai/code/session_014YjPMViNrZ7zBVgUQzwEKk
Hermes basic-auth is password-only, so bare / redirects into
/auth/login?provider=basic and 500s. Print the pretty dashboard host,
edge-redirect Exact / → /auth/password-login on the dashboard HTTPRoute,
document credentials, and smoke-check root + password-login in flow-04.
Hackathon setup feedback: pin OBOL_RELEASE to a current tag, document
hosts resume + OBOL_NONINTERACTIVE, Ollama-skip skipping Hermes, dormant
tunnel, and that Traefik needs Host: obol.stack (localhost:8080 is 404).
Include a GitBook gap list for docs.obol.org.
Resolve README conflict by keeping v0.13 install/hosts guidance and the
Hermes dashboard password-login section.
@bussyjd bussyjd requested a review from OisinKyne July 15, 2026 15:16

@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.

There's a dud file in one of the sub PRs that we probably should delete before merging this

bussyjd added 10 commits July 15, 2026 21:06
Two ServiceOffers with the same name in different namespaces both wrote
to x402/so-<name>-backend-grant, overwriting each other and flapping
backendRefs. Include the offer namespace in the grant name.
Previously any status <500 counted as healthy, so a 404 healthPath left
offers Ready while paid traffic failed. Match real liveness: 2xx only.
…iddlewares

Combining --max-in-flight and --rps produced one Middleware CR with both
types; Traefik rejected it while the offer still reported Ready. Emit one
CR per type, attach both ExtensionRefs, and delete the legacy -limits CR.
Dedicated-origin routes rewrite /path into /services/<name>/path before
the verifier; challenges still advertised the internal path. Also default
public hosts to https so TLS-terminated tunnels do not leak http://
resource URLs that break x402scan discovery.
obol sell register left ServiceOffers created with --no-register stuck
at registration.enabled=false / Registered=Disabled while the on-chain
AgentIdentity already had an agentId. After a successful register, patch
those offers enabled=true and treat a known agentId as Registered=True
even when RegistrationRequest phase is empty.
@bussyjd

bussyjd commented Jul 15, 2026

Copy link
Copy Markdown
Contributor Author

Hackathon bugfix train packed (5 PRs)

Merged onto this integration branch after evaluation of the five highest-priority upstream bugs:

Priority PR Fix
1 #757 ReferenceGrant namespaced by offer ns (cross-ns collision)
2 #758 UpstreamHealthy requires 2xx (not <500)
3 #759 Split inFlightReq + rateLimit into two Traefik Middlewares
4 #760 402 resource.URL public path + https for dedicated hosts / tunnels
5 #761 Enable registration on offers after CLI ERC-8004 register; status with agentId

Unit tests green for serviceoffercontroller, x402, cmd/obol after merge.

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