chore(release): v0.13.0-rc4 candidate — 8 reviewed PRs (#726–#734) - #741

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

chore(release): v0.13.0-rc4 candidate — 8 reviewed PRs (#726–#734)#741
OisinKyne merged 20 commits into
mainfrom
integration/v0.13.0-rc4

Conversation

@bussyjd

Copy link
Copy Markdown
Contributor

Collects the v0.13.0-rc4 candidate: eight reviewed PRs merged onto current main, plus a CRD regen for the combined types.

What's in it

PRAreaFable verdict
#726CI: resolve stack images by short SHA, drop repin trainship-with-caveat
#728controller: render Hermes config from Agent CR + hash-skip (stops resync-wipe)ship-with-caveat
#729hermes: HERMES_WRITE_SAFE_ROOT for the v2026.7 imageship
#730skills: inspect + bridging, arbitrum/robinhood chainsship-with-caveat
#731storefront: theme presets + seller identityship-with-caveat
#732storefront: richtext descriptions + per-hostname brandingship
#733storefront: custom CSS themesship
#734claude: plugin-version update nudgeship

Each was reviewed one-by-one by a Fable-5 panel — 4 ship / 4 ship-with-caveat / 0 hold. Direction assessed sound: a clean 3-layer storefront branding system (presets → per-hostname → custom CSS) with every injection surface routed through one sanitizer + XSS corpus test.

Local validation (rc4 tip)

  • go build ./... ✓ · go vet ✓ · tests for controller/x402/storefront/hermes/images/embed ✓
  • CRD generation up-to-date ✓ (regenerated serviceoffer-crd.yaml + deepcopy for the merged spec.branding + AgentSpec fields — one stacked branch's committed CRD lagged its Go types).

Rollout caveats for silvernuc3 (from the review)

PR descriptions on #731/#732 are shifted by one (each describes the next PR's feature) — diffs are correct; fix copy before final.

https://claude.ai/code/session_01VquWN9UMaSHH7MHGcG8bw1

bussyjdand others added 20 commits July 9, 2026 11:08
Stop storing x402 image digests in git. Embedded templates use
:__OBOL_IMAGE__; CopyInfrastructure rewrites via internal/images to
repo:<GitCommit>@sha256:<index-digest> at apply time (short-SHA tag
privileged; digest bound from GHCR when reachable). Dev still uses
dev-<sha>.
Delete release-prep, repin/verify-x402-pins scripts, and continuous
open-repin. Release gate is verify-release-images.sh (GHCR tags exist
for the commit short SHA). Publish job-broker with the other components.
Supersedes #725 (job-broker publish without expanding the repin regime).
Cut multi-arch publish from ~20–40m to a few minutes:
- Dockerfile.x402 multi-target: one shared builder builds all five
pure-Go binaries; final distroless stages stay separate
- docker-bake.hcl + bake-action: single job, shared GHA cache scope
- FROM --platform=\$BUILDPLATFORM + GOARCH=\$TARGETARCH (CGO off) —
drop QEMU emulation that dominated wall time
- BuildKit cache mounts for modules + go-build
- .dockerignore: exclude web/** bulk (keep public-storefront), tests
Thin per-component Dockerfiles kept for local stack builds with the
same cross-compile + cache-mount pattern.
Address review: apply-time re-fetch of GHCR digests would pick up a
retagged short-SHA on the next stack up. Bind the multi-arch index
digest on first resolve for each repo:GitCommit, store it in
$OBOL_CONFIG_DIR/image-digests.json, and reuse it on later applies
(unless OBOL_REFRESH_IMAGE_DIGESTS=true). Document the threat model
in docs/release-images.md.
…s from Agent CR
Additive AgentSpec fields (modelProvider, mcpServers, maxTurns,
disabledToolsets) threaded through renderHermesConfig so the CR is the
source of truth for the agent's inference provider and paid MCP wiring.
Unset fields render byte-identical to the prior fixed template (no CRD
version bump, no behavior change for existing agents).
Claude-Session: https://claude.ai/code/session_01VquWN9UMaSHH7MHGcG8bw1
…rift condition
Gate the per-agent hermes-config ConfigMap write on a content-hash
annotation (obol.org/hermes-config-hash) stored on the live ConfigMap.
Skip the apply when the freshly-rendered desired hash matches the stored
annotation — so an unchanged config is not rewritten on every reconcile
or controller restart. This ends the every-'obol stack up' re-provision
that silently wiped operator config (now CR-driven after b7b1bf4).
The skip decision is purely desiredHash == storedAnnotation, never
desired-vs-live-content, so operator edits are not treated as drift to
revert. Out-of-band ConfigMap edits are surfaced via a new ConfigDrift
status condition instead of being clobbered. Annotation lives on the
persistent ConfigMap so the skip survives controller-pod restarts.
Claude-Session: https://claude.ai/code/session_01VquWN9UMaSHH7MHGcG8bw1
Combined AgentSpec config fields (#728) with storefront spec.branding
(#731-#733) required a fresh controller-gen pass; the stacked branches'
committed CRD lagged the merged Go types. No hand edits.
Claude-Session: https://claude.ai/code/session_01VquWN9UMaSHH7MHGcG8bw1

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

Are these caveats dealt with in this PR or do they need to be dealt with? the swap to light theme default is deliberate, for one.

@OisinKyne
OisinKyne merged commit cc75342 into mainJul 13, 2026
11 checks passed
@OisinKyne
OisinKyne deleted the integration/v0.13.0-rc4 branch July 13, 2026 17:51
Sign up for freeto 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

@bussyjd@OisinKyne
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

chore(release): v0.13.0-rc4 candidate — 8 reviewed PRs (#726–#734) - #741

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

chore(release): v0.13.0-rc4 candidate — 8 reviewed PRs (#726–#734)#741
OisinKyne merged 20 commits into
mainfrom
integration/v0.13.0-rc4

Conversation

@bussyjd

Copy link
Copy Markdown
Contributor

Collects the v0.13.0-rc4 candidate: eight reviewed PRs merged onto current main, plus a CRD regen for the combined types.

What's in it

PRAreaFable verdict
#726CI: resolve stack images by short SHA, drop repin trainship-with-caveat
#728controller: render Hermes config from Agent CR + hash-skip (stops resync-wipe)ship-with-caveat
#729hermes: HERMES_WRITE_SAFE_ROOT for the v2026.7 imageship
#730skills: inspect + bridging, arbitrum/robinhood chainsship-with-caveat
#731storefront: theme presets + seller identityship-with-caveat
#732storefront: richtext descriptions + per-hostname brandingship
#733storefront: custom CSS themesship
#734claude: plugin-version update nudgeship

Each was reviewed one-by-one by a Fable-5 panel — 4 ship / 4 ship-with-caveat / 0 hold. Direction assessed sound: a clean 3-layer storefront branding system (presets → per-hostname → custom CSS) with every injection surface routed through one sanitizer + XSS corpus test.

Local validation (rc4 tip)

  • go build ./... ✓ · go vet ✓ · tests for controller/x402/storefront/hermes/images/embed ✓
  • CRD generation up-to-date ✓ (regenerated serviceoffer-crd.yaml + deepcopy for the merged spec.branding + AgentSpec fields — one stacked branch's committed CRD lagged its Go types).

Rollout caveats for silvernuc3 (from the review)

PR descriptions on #731/#732 are shifted by one (each describes the next PR's feature) — diffs are correct; fix copy before final.

https://claude.ai/code/session_01VquWN9UMaSHH7MHGcG8bw1

bussyjdand others added 20 commits July 9, 2026 11:08
Stop storing x402 image digests in git. Embedded templates use
:__OBOL_IMAGE__; CopyInfrastructure rewrites via internal/images to
repo:<GitCommit>@sha256:<index-digest> at apply time (short-SHA tag
privileged; digest bound from GHCR when reachable). Dev still uses
dev-<sha>.
Delete release-prep, repin/verify-x402-pins scripts, and continuous
open-repin. Release gate is verify-release-images.sh (GHCR tags exist
for the commit short SHA). Publish job-broker with the other components.
Supersedes #725 (job-broker publish without expanding the repin regime).
Cut multi-arch publish from ~20–40m to a few minutes:
- Dockerfile.x402 multi-target: one shared builder builds all five
pure-Go binaries; final distroless stages stay separate
- docker-bake.hcl + bake-action: single job, shared GHA cache scope
- FROM --platform=\$BUILDPLATFORM + GOARCH=\$TARGETARCH (CGO off) —
drop QEMU emulation that dominated wall time
- BuildKit cache mounts for modules + go-build
- .dockerignore: exclude web/** bulk (keep public-storefront), tests
Thin per-component Dockerfiles kept for local stack builds with the
same cross-compile + cache-mount pattern.
Address review: apply-time re-fetch of GHCR digests would pick up a
retagged short-SHA on the next stack up. Bind the multi-arch index
digest on first resolve for each repo:GitCommit, store it in
$OBOL_CONFIG_DIR/image-digests.json, and reuse it on later applies
(unless OBOL_REFRESH_IMAGE_DIGESTS=true). Document the threat model
in docs/release-images.md.
…s from Agent CR
Additive AgentSpec fields (modelProvider, mcpServers, maxTurns,
disabledToolsets) threaded through renderHermesConfig so the CR is the
source of truth for the agent's inference provider and paid MCP wiring.
Unset fields render byte-identical to the prior fixed template (no CRD
version bump, no behavior change for existing agents).
Claude-Session: https://claude.ai/code/session_01VquWN9UMaSHH7MHGcG8bw1
…rift condition
Gate the per-agent hermes-config ConfigMap write on a content-hash
annotation (obol.org/hermes-config-hash) stored on the live ConfigMap.
Skip the apply when the freshly-rendered desired hash matches the stored
annotation — so an unchanged config is not rewritten on every reconcile
or controller restart. This ends the every-'obol stack up' re-provision
that silently wiped operator config (now CR-driven after b7b1bf4).
The skip decision is purely desiredHash == storedAnnotation, never
desired-vs-live-content, so operator edits are not treated as drift to
revert. Out-of-band ConfigMap edits are surfaced via a new ConfigDrift
status condition instead of being clobbered. Annotation lives on the
persistent ConfigMap so the skip survives controller-pod restarts.
Claude-Session: https://claude.ai/code/session_01VquWN9UMaSHH7MHGcG8bw1
Combined AgentSpec config fields (#728) with storefront spec.branding
(#731-#733) required a fresh controller-gen pass; the stacked branches'
committed CRD lagged the merged Go types. No hand edits.
Claude-Session: https://claude.ai/code/session_01VquWN9UMaSHH7MHGcG8bw1

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

Are these caveats dealt with in this PR or do they need to be dealt with? the swap to light theme default is deliberate, for one.

@OisinKyne
OisinKyne merged commit cc75342 into mainJul 13, 2026
11 checks passed
@OisinKyne
OisinKyne deleted the integration/v0.13.0-rc4 branch July 13, 2026 17:51
Sign up for freeto 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

@bussyjd@OisinKyne
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

chore(release): v0.13.0-rc4 candidate — 8 reviewed PRs (#726–#734) - #741

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

chore(release): v0.13.0-rc4 candidate — 8 reviewed PRs (#726–#734)#741
OisinKyne merged 20 commits into
mainfrom
integration/v0.13.0-rc4

Conversation

@bussyjd

Copy link
Copy Markdown
Contributor

Collects the v0.13.0-rc4 candidate: eight reviewed PRs merged onto current main, plus a CRD regen for the combined types.

What's in it

PRAreaFable verdict
#726CI: resolve stack images by short SHA, drop repin trainship-with-caveat
#728controller: render Hermes config from Agent CR + hash-skip (stops resync-wipe)ship-with-caveat
#729hermes: HERMES_WRITE_SAFE_ROOT for the v2026.7 imageship
#730skills: inspect + bridging, arbitrum/robinhood chainsship-with-caveat
#731storefront: theme presets + seller identityship-with-caveat
#732storefront: richtext descriptions + per-hostname brandingship
#733storefront: custom CSS themesship
#734claude: plugin-version update nudgeship

Each was reviewed one-by-one by a Fable-5 panel — 4 ship / 4 ship-with-caveat / 0 hold. Direction assessed sound: a clean 3-layer storefront branding system (presets → per-hostname → custom CSS) with every injection surface routed through one sanitizer + XSS corpus test.

Local validation (rc4 tip)

  • go build ./... ✓ · go vet ✓ · tests for controller/x402/storefront/hermes/images/embed ✓
  • CRD generation up-to-date ✓ (regenerated serviceoffer-crd.yaml + deepcopy for the merged spec.branding + AgentSpec fields — one stacked branch's committed CRD lagged its Go types).

Rollout caveats for silvernuc3 (from the review)

PR descriptions on #731/#732 are shifted by one (each describes the next PR's feature) — diffs are correct; fix copy before final.

https://claude.ai/code/session_01VquWN9UMaSHH7MHGcG8bw1

bussyjdand others added 20 commits July 9, 2026 11:08
Stop storing x402 image digests in git. Embedded templates use
:__OBOL_IMAGE__; CopyInfrastructure rewrites via internal/images to
repo:<GitCommit>@sha256:<index-digest> at apply time (short-SHA tag
privileged; digest bound from GHCR when reachable). Dev still uses
dev-<sha>.
Delete release-prep, repin/verify-x402-pins scripts, and continuous
open-repin. Release gate is verify-release-images.sh (GHCR tags exist
for the commit short SHA). Publish job-broker with the other components.
Supersedes #725 (job-broker publish without expanding the repin regime).
Cut multi-arch publish from ~20–40m to a few minutes:
- Dockerfile.x402 multi-target: one shared builder builds all five
pure-Go binaries; final distroless stages stay separate
- docker-bake.hcl + bake-action: single job, shared GHA cache scope
- FROM --platform=\$BUILDPLATFORM + GOARCH=\$TARGETARCH (CGO off) —
drop QEMU emulation that dominated wall time
- BuildKit cache mounts for modules + go-build
- .dockerignore: exclude web/** bulk (keep public-storefront), tests
Thin per-component Dockerfiles kept for local stack builds with the
same cross-compile + cache-mount pattern.
Address review: apply-time re-fetch of GHCR digests would pick up a
retagged short-SHA on the next stack up. Bind the multi-arch index
digest on first resolve for each repo:GitCommit, store it in
$OBOL_CONFIG_DIR/image-digests.json, and reuse it on later applies
(unless OBOL_REFRESH_IMAGE_DIGESTS=true). Document the threat model
in docs/release-images.md.
…s from Agent CR
Additive AgentSpec fields (modelProvider, mcpServers, maxTurns,
disabledToolsets) threaded through renderHermesConfig so the CR is the
source of truth for the agent's inference provider and paid MCP wiring.
Unset fields render byte-identical to the prior fixed template (no CRD
version bump, no behavior change for existing agents).
Claude-Session: https://claude.ai/code/session_01VquWN9UMaSHH7MHGcG8bw1
…rift condition
Gate the per-agent hermes-config ConfigMap write on a content-hash
annotation (obol.org/hermes-config-hash) stored on the live ConfigMap.
Skip the apply when the freshly-rendered desired hash matches the stored
annotation — so an unchanged config is not rewritten on every reconcile
or controller restart. This ends the every-'obol stack up' re-provision
that silently wiped operator config (now CR-driven after b7b1bf4).
The skip decision is purely desiredHash == storedAnnotation, never
desired-vs-live-content, so operator edits are not treated as drift to
revert. Out-of-band ConfigMap edits are surfaced via a new ConfigDrift
status condition instead of being clobbered. Annotation lives on the
persistent ConfigMap so the skip survives controller-pod restarts.
Claude-Session: https://claude.ai/code/session_01VquWN9UMaSHH7MHGcG8bw1
Combined AgentSpec config fields (#728) with storefront spec.branding
(#731-#733) required a fresh controller-gen pass; the stacked branches'
committed CRD lagged the merged Go types. No hand edits.
Claude-Session: https://claude.ai/code/session_01VquWN9UMaSHH7MHGcG8bw1

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

Are these caveats dealt with in this PR or do they need to be dealt with? the swap to light theme default is deliberate, for one.

@OisinKyne
OisinKyne merged commit cc75342 into mainJul 13, 2026
11 checks passed
@OisinKyne
OisinKyne deleted the integration/v0.13.0-rc4 branch July 13, 2026 17:51
Sign up for freeto 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

@bussyjd@OisinKyne
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

chore(release): v0.13.0-rc4 candidate — 8 reviewed PRs (#726–#734) - #741

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

chore(release): v0.13.0-rc4 candidate — 8 reviewed PRs (#726–#734)#741
OisinKyne merged 20 commits into
mainfrom
integration/v0.13.0-rc4

Conversation

@bussyjd

Copy link
Copy Markdown
Contributor

Collects the v0.13.0-rc4 candidate: eight reviewed PRs merged onto current main, plus a CRD regen for the combined types.

What's in it

PRAreaFable verdict
#726CI: resolve stack images by short SHA, drop repin trainship-with-caveat
#728controller: render Hermes config from Agent CR + hash-skip (stops resync-wipe)ship-with-caveat
#729hermes: HERMES_WRITE_SAFE_ROOT for the v2026.7 imageship
#730skills: inspect + bridging, arbitrum/robinhood chainsship-with-caveat
#731storefront: theme presets + seller identityship-with-caveat
#732storefront: richtext descriptions + per-hostname brandingship
#733storefront: custom CSS themesship
#734claude: plugin-version update nudgeship

Each was reviewed one-by-one by a Fable-5 panel — 4 ship / 4 ship-with-caveat / 0 hold. Direction assessed sound: a clean 3-layer storefront branding system (presets → per-hostname → custom CSS) with every injection surface routed through one sanitizer + XSS corpus test.

Local validation (rc4 tip)

  • go build ./... ✓ · go vet ✓ · tests for controller/x402/storefront/hermes/images/embed ✓
  • CRD generation up-to-date ✓ (regenerated serviceoffer-crd.yaml + deepcopy for the merged spec.branding + AgentSpec fields — one stacked branch's committed CRD lagged its Go types).

Rollout caveats for silvernuc3 (from the review)

PR descriptions on #731/#732 are shifted by one (each describes the next PR's feature) — diffs are correct; fix copy before final.

https://claude.ai/code/session_01VquWN9UMaSHH7MHGcG8bw1

bussyjdand others added 20 commits July 9, 2026 11:08
Stop storing x402 image digests in git. Embedded templates use
:__OBOL_IMAGE__; CopyInfrastructure rewrites via internal/images to
repo:<GitCommit>@sha256:<index-digest> at apply time (short-SHA tag
privileged; digest bound from GHCR when reachable). Dev still uses
dev-<sha>.
Delete release-prep, repin/verify-x402-pins scripts, and continuous
open-repin. Release gate is verify-release-images.sh (GHCR tags exist
for the commit short SHA). Publish job-broker with the other components.
Supersedes #725 (job-broker publish without expanding the repin regime).
Cut multi-arch publish from ~20–40m to a few minutes:
- Dockerfile.x402 multi-target: one shared builder builds all five
pure-Go binaries; final distroless stages stay separate
- docker-bake.hcl + bake-action: single job, shared GHA cache scope
- FROM --platform=\$BUILDPLATFORM + GOARCH=\$TARGETARCH (CGO off) —
drop QEMU emulation that dominated wall time
- BuildKit cache mounts for modules + go-build
- .dockerignore: exclude web/** bulk (keep public-storefront), tests
Thin per-component Dockerfiles kept for local stack builds with the
same cross-compile + cache-mount pattern.
Address review: apply-time re-fetch of GHCR digests would pick up a
retagged short-SHA on the next stack up. Bind the multi-arch index
digest on first resolve for each repo:GitCommit, store it in
$OBOL_CONFIG_DIR/image-digests.json, and reuse it on later applies
(unless OBOL_REFRESH_IMAGE_DIGESTS=true). Document the threat model
in docs/release-images.md.
…s from Agent CR
Additive AgentSpec fields (modelProvider, mcpServers, maxTurns,
disabledToolsets) threaded through renderHermesConfig so the CR is the
source of truth for the agent's inference provider and paid MCP wiring.
Unset fields render byte-identical to the prior fixed template (no CRD
version bump, no behavior change for existing agents).
Claude-Session: https://claude.ai/code/session_01VquWN9UMaSHH7MHGcG8bw1
…rift condition
Gate the per-agent hermes-config ConfigMap write on a content-hash
annotation (obol.org/hermes-config-hash) stored on the live ConfigMap.
Skip the apply when the freshly-rendered desired hash matches the stored
annotation — so an unchanged config is not rewritten on every reconcile
or controller restart. This ends the every-'obol stack up' re-provision
that silently wiped operator config (now CR-driven after b7b1bf4).
The skip decision is purely desiredHash == storedAnnotation, never
desired-vs-live-content, so operator edits are not treated as drift to
revert. Out-of-band ConfigMap edits are surfaced via a new ConfigDrift
status condition instead of being clobbered. Annotation lives on the
persistent ConfigMap so the skip survives controller-pod restarts.
Claude-Session: https://claude.ai/code/session_01VquWN9UMaSHH7MHGcG8bw1
Combined AgentSpec config fields (#728) with storefront spec.branding
(#731-#733) required a fresh controller-gen pass; the stacked branches'
committed CRD lagged the merged Go types. No hand edits.
Claude-Session: https://claude.ai/code/session_01VquWN9UMaSHH7MHGcG8bw1

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

Are these caveats dealt with in this PR or do they need to be dealt with? the swap to light theme default is deliberate, for one.

@OisinKyne
OisinKyne merged commit cc75342 into mainJul 13, 2026
11 checks passed
@OisinKyne
OisinKyne deleted the integration/v0.13.0-rc4 branch July 13, 2026 17:51
Sign up for freeto 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

@bussyjd@OisinKyne
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

chore(release): v0.13.0-rc4 candidate — 8 reviewed PRs (#726–#734) - #741

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

chore(release): v0.13.0-rc4 candidate — 8 reviewed PRs (#726–#734)#741
OisinKyne merged 20 commits into
mainfrom
integration/v0.13.0-rc4

Conversation

@bussyjd

Copy link
Copy Markdown
Contributor

Collects the v0.13.0-rc4 candidate: eight reviewed PRs merged onto current main, plus a CRD regen for the combined types.

What's in it

PRAreaFable verdict
#726CI: resolve stack images by short SHA, drop repin trainship-with-caveat
#728controller: render Hermes config from Agent CR + hash-skip (stops resync-wipe)ship-with-caveat
#729hermes: HERMES_WRITE_SAFE_ROOT for the v2026.7 imageship
#730skills: inspect + bridging, arbitrum/robinhood chainsship-with-caveat
#731storefront: theme presets + seller identityship-with-caveat
#732storefront: richtext descriptions + per-hostname brandingship
#733storefront: custom CSS themesship
#734claude: plugin-version update nudgeship

Each was reviewed one-by-one by a Fable-5 panel — 4 ship / 4 ship-with-caveat / 0 hold. Direction assessed sound: a clean 3-layer storefront branding system (presets → per-hostname → custom CSS) with every injection surface routed through one sanitizer + XSS corpus test.

Local validation (rc4 tip)

  • go build ./... ✓ · go vet ✓ · tests for controller/x402/storefront/hermes/images/embed ✓
  • CRD generation up-to-date ✓ (regenerated serviceoffer-crd.yaml + deepcopy for the merged spec.branding + AgentSpec fields — one stacked branch's committed CRD lagged its Go types).

Rollout caveats for silvernuc3 (from the review)

PR descriptions on #731/#732 are shifted by one (each describes the next PR's feature) — diffs are correct; fix copy before final.

https://claude.ai/code/session_01VquWN9UMaSHH7MHGcG8bw1

bussyjdand others added 20 commits July 9, 2026 11:08
Stop storing x402 image digests in git. Embedded templates use
:__OBOL_IMAGE__; CopyInfrastructure rewrites via internal/images to
repo:<GitCommit>@sha256:<index-digest> at apply time (short-SHA tag
privileged; digest bound from GHCR when reachable). Dev still uses
dev-<sha>.
Delete release-prep, repin/verify-x402-pins scripts, and continuous
open-repin. Release gate is verify-release-images.sh (GHCR tags exist
for the commit short SHA). Publish job-broker with the other components.
Supersedes #725 (job-broker publish without expanding the repin regime).
Cut multi-arch publish from ~20–40m to a few minutes:
- Dockerfile.x402 multi-target: one shared builder builds all five
pure-Go binaries; final distroless stages stay separate
- docker-bake.hcl + bake-action: single job, shared GHA cache scope
- FROM --platform=\$BUILDPLATFORM + GOARCH=\$TARGETARCH (CGO off) —
drop QEMU emulation that dominated wall time
- BuildKit cache mounts for modules + go-build
- .dockerignore: exclude web/** bulk (keep public-storefront), tests
Thin per-component Dockerfiles kept for local stack builds with the
same cross-compile + cache-mount pattern.
Address review: apply-time re-fetch of GHCR digests would pick up a
retagged short-SHA on the next stack up. Bind the multi-arch index
digest on first resolve for each repo:GitCommit, store it in
$OBOL_CONFIG_DIR/image-digests.json, and reuse it on later applies
(unless OBOL_REFRESH_IMAGE_DIGESTS=true). Document the threat model
in docs/release-images.md.
…s from Agent CR
Additive AgentSpec fields (modelProvider, mcpServers, maxTurns,
disabledToolsets) threaded through renderHermesConfig so the CR is the
source of truth for the agent's inference provider and paid MCP wiring.
Unset fields render byte-identical to the prior fixed template (no CRD
version bump, no behavior change for existing agents).
Claude-Session: https://claude.ai/code/session_01VquWN9UMaSHH7MHGcG8bw1
…rift condition
Gate the per-agent hermes-config ConfigMap write on a content-hash
annotation (obol.org/hermes-config-hash) stored on the live ConfigMap.
Skip the apply when the freshly-rendered desired hash matches the stored
annotation — so an unchanged config is not rewritten on every reconcile
or controller restart. This ends the every-'obol stack up' re-provision
that silently wiped operator config (now CR-driven after b7b1bf4).
The skip decision is purely desiredHash == storedAnnotation, never
desired-vs-live-content, so operator edits are not treated as drift to
revert. Out-of-band ConfigMap edits are surfaced via a new ConfigDrift
status condition instead of being clobbered. Annotation lives on the
persistent ConfigMap so the skip survives controller-pod restarts.
Claude-Session: https://claude.ai/code/session_01VquWN9UMaSHH7MHGcG8bw1
Combined AgentSpec config fields (#728) with storefront spec.branding
(#731-#733) required a fresh controller-gen pass; the stacked branches'
committed CRD lagged the merged Go types. No hand edits.
Claude-Session: https://claude.ai/code/session_01VquWN9UMaSHH7MHGcG8bw1

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

Are these caveats dealt with in this PR or do they need to be dealt with? the swap to light theme default is deliberate, for one.

@OisinKyne
OisinKyne merged commit cc75342 into mainJul 13, 2026
11 checks passed
@OisinKyne
OisinKyne deleted the integration/v0.13.0-rc4 branch July 13, 2026 17:51
Sign up for freeto 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

@bussyjd@OisinKyne
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

chore(release): v0.13.0-rc4 candidate — 8 reviewed PRs (#726–#734) - #741

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

chore(release): v0.13.0-rc4 candidate — 8 reviewed PRs (#726–#734)#741
OisinKyne merged 20 commits into
mainfrom
integration/v0.13.0-rc4

Conversation

@bussyjd

Copy link
Copy Markdown
Contributor

Collects the v0.13.0-rc4 candidate: eight reviewed PRs merged onto current main, plus a CRD regen for the combined types.

What's in it

PRAreaFable verdict
#726CI: resolve stack images by short SHA, drop repin trainship-with-caveat
#728controller: render Hermes config from Agent CR + hash-skip (stops resync-wipe)ship-with-caveat
#729hermes: HERMES_WRITE_SAFE_ROOT for the v2026.7 imageship
#730skills: inspect + bridging, arbitrum/robinhood chainsship-with-caveat
#731storefront: theme presets + seller identityship-with-caveat
#732storefront: richtext descriptions + per-hostname brandingship
#733storefront: custom CSS themesship
#734claude: plugin-version update nudgeship

Each was reviewed one-by-one by a Fable-5 panel — 4 ship / 4 ship-with-caveat / 0 hold. Direction assessed sound: a clean 3-layer storefront branding system (presets → per-hostname → custom CSS) with every injection surface routed through one sanitizer + XSS corpus test.

Local validation (rc4 tip)

  • go build ./... ✓ · go vet ✓ · tests for controller/x402/storefront/hermes/images/embed ✓
  • CRD generation up-to-date ✓ (regenerated serviceoffer-crd.yaml + deepcopy for the merged spec.branding + AgentSpec fields — one stacked branch's committed CRD lagged its Go types).

Rollout caveats for silvernuc3 (from the review)

PR descriptions on #731/#732 are shifted by one (each describes the next PR's feature) — diffs are correct; fix copy before final.

https://claude.ai/code/session_01VquWN9UMaSHH7MHGcG8bw1

bussyjdand others added 20 commits July 9, 2026 11:08
Stop storing x402 image digests in git. Embedded templates use
:__OBOL_IMAGE__; CopyInfrastructure rewrites via internal/images to
repo:<GitCommit>@sha256:<index-digest> at apply time (short-SHA tag
privileged; digest bound from GHCR when reachable). Dev still uses
dev-<sha>.
Delete release-prep, repin/verify-x402-pins scripts, and continuous
open-repin. Release gate is verify-release-images.sh (GHCR tags exist
for the commit short SHA). Publish job-broker with the other components.
Supersedes #725 (job-broker publish without expanding the repin regime).
Cut multi-arch publish from ~20–40m to a few minutes:
- Dockerfile.x402 multi-target: one shared builder builds all five
pure-Go binaries; final distroless stages stay separate
- docker-bake.hcl + bake-action: single job, shared GHA cache scope
- FROM --platform=\$BUILDPLATFORM + GOARCH=\$TARGETARCH (CGO off) —
drop QEMU emulation that dominated wall time
- BuildKit cache mounts for modules + go-build
- .dockerignore: exclude web/** bulk (keep public-storefront), tests
Thin per-component Dockerfiles kept for local stack builds with the
same cross-compile + cache-mount pattern.
Address review: apply-time re-fetch of GHCR digests would pick up a
retagged short-SHA on the next stack up. Bind the multi-arch index
digest on first resolve for each repo:GitCommit, store it in
$OBOL_CONFIG_DIR/image-digests.json, and reuse it on later applies
(unless OBOL_REFRESH_IMAGE_DIGESTS=true). Document the threat model
in docs/release-images.md.
…s from Agent CR
Additive AgentSpec fields (modelProvider, mcpServers, maxTurns,
disabledToolsets) threaded through renderHermesConfig so the CR is the
source of truth for the agent's inference provider and paid MCP wiring.
Unset fields render byte-identical to the prior fixed template (no CRD
version bump, no behavior change for existing agents).
Claude-Session: https://claude.ai/code/session_01VquWN9UMaSHH7MHGcG8bw1
…rift condition
Gate the per-agent hermes-config ConfigMap write on a content-hash
annotation (obol.org/hermes-config-hash) stored on the live ConfigMap.
Skip the apply when the freshly-rendered desired hash matches the stored
annotation — so an unchanged config is not rewritten on every reconcile
or controller restart. This ends the every-'obol stack up' re-provision
that silently wiped operator config (now CR-driven after b7b1bf4).
The skip decision is purely desiredHash == storedAnnotation, never
desired-vs-live-content, so operator edits are not treated as drift to
revert. Out-of-band ConfigMap edits are surfaced via a new ConfigDrift
status condition instead of being clobbered. Annotation lives on the
persistent ConfigMap so the skip survives controller-pod restarts.
Claude-Session: https://claude.ai/code/session_01VquWN9UMaSHH7MHGcG8bw1
Combined AgentSpec config fields (#728) with storefront spec.branding
(#731-#733) required a fresh controller-gen pass; the stacked branches'
committed CRD lagged the merged Go types. No hand edits.
Claude-Session: https://claude.ai/code/session_01VquWN9UMaSHH7MHGcG8bw1

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

Are these caveats dealt with in this PR or do they need to be dealt with? the swap to light theme default is deliberate, for one.

@OisinKyne
OisinKyne merged commit cc75342 into mainJul 13, 2026
11 checks passed
@OisinKyne
OisinKyne deleted the integration/v0.13.0-rc4 branch July 13, 2026 17:51
Sign up for freeto 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

@bussyjd@OisinKyne
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

chore(release): v0.13.0-rc4 candidate — 8 reviewed PRs (#726–#734) - #741

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

chore(release): v0.13.0-rc4 candidate — 8 reviewed PRs (#726–#734)#741
OisinKyne merged 20 commits into
mainfrom
integration/v0.13.0-rc4

Conversation

@bussyjd

Copy link
Copy Markdown
Contributor

Collects the v0.13.0-rc4 candidate: eight reviewed PRs merged onto current main, plus a CRD regen for the combined types.

What's in it

PRAreaFable verdict
#726CI: resolve stack images by short SHA, drop repin trainship-with-caveat
#728controller: render Hermes config from Agent CR + hash-skip (stops resync-wipe)ship-with-caveat
#729hermes: HERMES_WRITE_SAFE_ROOT for the v2026.7 imageship
#730skills: inspect + bridging, arbitrum/robinhood chainsship-with-caveat
#731storefront: theme presets + seller identityship-with-caveat
#732storefront: richtext descriptions + per-hostname brandingship
#733storefront: custom CSS themesship
#734claude: plugin-version update nudgeship

Each was reviewed one-by-one by a Fable-5 panel — 4 ship / 4 ship-with-caveat / 0 hold. Direction assessed sound: a clean 3-layer storefront branding system (presets → per-hostname → custom CSS) with every injection surface routed through one sanitizer + XSS corpus test.

Local validation (rc4 tip)

  • go build ./... ✓ · go vet ✓ · tests for controller/x402/storefront/hermes/images/embed ✓
  • CRD generation up-to-date ✓ (regenerated serviceoffer-crd.yaml + deepcopy for the merged spec.branding + AgentSpec fields — one stacked branch's committed CRD lagged its Go types).

Rollout caveats for silvernuc3 (from the review)

PR descriptions on #731/#732 are shifted by one (each describes the next PR's feature) — diffs are correct; fix copy before final.

https://claude.ai/code/session_01VquWN9UMaSHH7MHGcG8bw1

bussyjdand others added 20 commits July 9, 2026 11:08
Stop storing x402 image digests in git. Embedded templates use
:__OBOL_IMAGE__; CopyInfrastructure rewrites via internal/images to
repo:<GitCommit>@sha256:<index-digest> at apply time (short-SHA tag
privileged; digest bound from GHCR when reachable). Dev still uses
dev-<sha>.
Delete release-prep, repin/verify-x402-pins scripts, and continuous
open-repin. Release gate is verify-release-images.sh (GHCR tags exist
for the commit short SHA). Publish job-broker with the other components.
Supersedes #725 (job-broker publish without expanding the repin regime).
Cut multi-arch publish from ~20–40m to a few minutes:
- Dockerfile.x402 multi-target: one shared builder builds all five
pure-Go binaries; final distroless stages stay separate
- docker-bake.hcl + bake-action: single job, shared GHA cache scope
- FROM --platform=\$BUILDPLATFORM + GOARCH=\$TARGETARCH (CGO off) —
drop QEMU emulation that dominated wall time
- BuildKit cache mounts for modules + go-build
- .dockerignore: exclude web/** bulk (keep public-storefront), tests
Thin per-component Dockerfiles kept for local stack builds with the
same cross-compile + cache-mount pattern.
Address review: apply-time re-fetch of GHCR digests would pick up a
retagged short-SHA on the next stack up. Bind the multi-arch index
digest on first resolve for each repo:GitCommit, store it in
$OBOL_CONFIG_DIR/image-digests.json, and reuse it on later applies
(unless OBOL_REFRESH_IMAGE_DIGESTS=true). Document the threat model
in docs/release-images.md.
…s from Agent CR
Additive AgentSpec fields (modelProvider, mcpServers, maxTurns,
disabledToolsets) threaded through renderHermesConfig so the CR is the
source of truth for the agent's inference provider and paid MCP wiring.
Unset fields render byte-identical to the prior fixed template (no CRD
version bump, no behavior change for existing agents).
Claude-Session: https://claude.ai/code/session_01VquWN9UMaSHH7MHGcG8bw1
…rift condition
Gate the per-agent hermes-config ConfigMap write on a content-hash
annotation (obol.org/hermes-config-hash) stored on the live ConfigMap.
Skip the apply when the freshly-rendered desired hash matches the stored
annotation — so an unchanged config is not rewritten on every reconcile
or controller restart. This ends the every-'obol stack up' re-provision
that silently wiped operator config (now CR-driven after b7b1bf4).
The skip decision is purely desiredHash == storedAnnotation, never
desired-vs-live-content, so operator edits are not treated as drift to
revert. Out-of-band ConfigMap edits are surfaced via a new ConfigDrift
status condition instead of being clobbered. Annotation lives on the
persistent ConfigMap so the skip survives controller-pod restarts.
Claude-Session: https://claude.ai/code/session_01VquWN9UMaSHH7MHGcG8bw1
Combined AgentSpec config fields (#728) with storefront spec.branding
(#731-#733) required a fresh controller-gen pass; the stacked branches'
committed CRD lagged the merged Go types. No hand edits.
Claude-Session: https://claude.ai/code/session_01VquWN9UMaSHH7MHGcG8bw1

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

Are these caveats dealt with in this PR or do they need to be dealt with? the swap to light theme default is deliberate, for one.

@OisinKyne
OisinKyne merged commit cc75342 into mainJul 13, 2026
11 checks passed
@OisinKyne
OisinKyne deleted the integration/v0.13.0-rc4 branch July 13, 2026 17:51
Sign up for freeto 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

@bussyjd@OisinKyne
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

chore(release): v0.13.0-rc4 candidate — 8 reviewed PRs (#726–#734) - #741

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

chore(release): v0.13.0-rc4 candidate — 8 reviewed PRs (#726–#734)#741
OisinKyne merged 20 commits into
mainfrom
integration/v0.13.0-rc4

Conversation

@bussyjd

Copy link
Copy Markdown
Contributor

Collects the v0.13.0-rc4 candidate: eight reviewed PRs merged onto current main, plus a CRD regen for the combined types.

What's in it

PRAreaFable verdict
#726CI: resolve stack images by short SHA, drop repin trainship-with-caveat
#728controller: render Hermes config from Agent CR + hash-skip (stops resync-wipe)ship-with-caveat
#729hermes: HERMES_WRITE_SAFE_ROOT for the v2026.7 imageship
#730skills: inspect + bridging, arbitrum/robinhood chainsship-with-caveat
#731storefront: theme presets + seller identityship-with-caveat
#732storefront: richtext descriptions + per-hostname brandingship
#733storefront: custom CSS themesship
#734claude: plugin-version update nudgeship

Each was reviewed one-by-one by a Fable-5 panel — 4 ship / 4 ship-with-caveat / 0 hold. Direction assessed sound: a clean 3-layer storefront branding system (presets → per-hostname → custom CSS) with every injection surface routed through one sanitizer + XSS corpus test.

Local validation (rc4 tip)

  • go build ./... ✓ · go vet ✓ · tests for controller/x402/storefront/hermes/images/embed ✓
  • CRD generation up-to-date ✓ (regenerated serviceoffer-crd.yaml + deepcopy for the merged spec.branding + AgentSpec fields — one stacked branch's committed CRD lagged its Go types).

Rollout caveats for silvernuc3 (from the review)

PR descriptions on #731/#732 are shifted by one (each describes the next PR's feature) — diffs are correct; fix copy before final.

https://claude.ai/code/session_01VquWN9UMaSHH7MHGcG8bw1

bussyjdand others added 20 commits July 9, 2026 11:08
Stop storing x402 image digests in git. Embedded templates use
:__OBOL_IMAGE__; CopyInfrastructure rewrites via internal/images to
repo:<GitCommit>@sha256:<index-digest> at apply time (short-SHA tag
privileged; digest bound from GHCR when reachable). Dev still uses
dev-<sha>.
Delete release-prep, repin/verify-x402-pins scripts, and continuous
open-repin. Release gate is verify-release-images.sh (GHCR tags exist
for the commit short SHA). Publish job-broker with the other components.
Supersedes #725 (job-broker publish without expanding the repin regime).
Cut multi-arch publish from ~20–40m to a few minutes:
- Dockerfile.x402 multi-target: one shared builder builds all five
pure-Go binaries; final distroless stages stay separate
- docker-bake.hcl + bake-action: single job, shared GHA cache scope
- FROM --platform=\$BUILDPLATFORM + GOARCH=\$TARGETARCH (CGO off) —
drop QEMU emulation that dominated wall time
- BuildKit cache mounts for modules + go-build
- .dockerignore: exclude web/** bulk (keep public-storefront), tests
Thin per-component Dockerfiles kept for local stack builds with the
same cross-compile + cache-mount pattern.
Address review: apply-time re-fetch of GHCR digests would pick up a
retagged short-SHA on the next stack up. Bind the multi-arch index
digest on first resolve for each repo:GitCommit, store it in
$OBOL_CONFIG_DIR/image-digests.json, and reuse it on later applies
(unless OBOL_REFRESH_IMAGE_DIGESTS=true). Document the threat model
in docs/release-images.md.
…s from Agent CR
Additive AgentSpec fields (modelProvider, mcpServers, maxTurns,
disabledToolsets) threaded through renderHermesConfig so the CR is the
source of truth for the agent's inference provider and paid MCP wiring.
Unset fields render byte-identical to the prior fixed template (no CRD
version bump, no behavior change for existing agents).
Claude-Session: https://claude.ai/code/session_01VquWN9UMaSHH7MHGcG8bw1
…rift condition
Gate the per-agent hermes-config ConfigMap write on a content-hash
annotation (obol.org/hermes-config-hash) stored on the live ConfigMap.
Skip the apply when the freshly-rendered desired hash matches the stored
annotation — so an unchanged config is not rewritten on every reconcile
or controller restart. This ends the every-'obol stack up' re-provision
that silently wiped operator config (now CR-driven after b7b1bf4).
The skip decision is purely desiredHash == storedAnnotation, never
desired-vs-live-content, so operator edits are not treated as drift to
revert. Out-of-band ConfigMap edits are surfaced via a new ConfigDrift
status condition instead of being clobbered. Annotation lives on the
persistent ConfigMap so the skip survives controller-pod restarts.
Claude-Session: https://claude.ai/code/session_01VquWN9UMaSHH7MHGcG8bw1
Combined AgentSpec config fields (#728) with storefront spec.branding
(#731-#733) required a fresh controller-gen pass; the stacked branches'
committed CRD lagged the merged Go types. No hand edits.
Claude-Session: https://claude.ai/code/session_01VquWN9UMaSHH7MHGcG8bw1

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

Are these caveats dealt with in this PR or do they need to be dealt with? the swap to light theme default is deliberate, for one.

@OisinKyne
OisinKyne merged commit cc75342 into mainJul 13, 2026
11 checks passed
@OisinKyne
OisinKyne deleted the integration/v0.13.0-rc4 branch July 13, 2026 17:51
Sign up for freeto 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

@bussyjd@OisinKyne