* fix(ci,charts,api): qa-loop iter-7 Fix#39 — bp-guacamole + bp-k8s-ws-proxy bootstrap-kit slots
Closes the scope-narrow confessed by Fix#36: bp-guacamole +
bp-k8s-ws-proxy chart skeletons existed at platform/* but lacked CI
image-build workflows + bootstrap-kit slots, so TC-228 / TC-230 /
TC-236 / TC-237 / TC-245 / TC-246 stayed FAIL with "deployment
NotFound".
CI workflows
------------
- .github/workflows/build-k8s-ws-proxy.yaml: Buildx + cosign keyless
sign + SBOM attestation flow on core/cmd/k8s-ws-proxy/**, then bumps
platform/k8s-ws-proxy/chart/values.yaml image.tag + Chart.yaml
patch version + dispatches blueprint-release.
- .github/workflows/build-bp-guacamole.yaml: mirrors upstream Apache
Guacamole 1.5.5 to GHCR (so every Sovereign pulls from a registry
we own — no Docker Hub rate limits, no upstream availability risk),
bumps values.yaml.image.{repository,tag} + Chart.yaml + dispatches
blueprint-release.
Charts (target-state)
---------------------
- bp-k8s-ws-proxy v0.1.1: canonical workload name `k8s-ws-proxy`
regardless of release name (DaemonSet + Service + ClusterRole +
ClusterRoleBinding + ServiceAccount all named `k8s-ws-proxy` so
matrix can address them by canonical short name).
- bp-guacamole v0.1.1: canonical short resource names (`guacd`,
`guacamole-server`, `guacamole-recordings`); GHCR-mirrored upstream
images; realm-patch ConfigMap correctly lands in `keycloak`
namespace (was: realm-name, which would have failed silently on
every Sovereign); `realmConfig.namespace` override surface added.
- Both charts: `catalyst.openova.io/smoke-render-mode: default-off`
annotation so blueprint-release smoke-render gate honors the
default-OFF render shape.
Bootstrap-kit slots
-------------------
- clusters/_template/bootstrap-kit/36-bp-k8s-ws-proxy.yaml +
37-bp-guacamole.yaml: dependsOn-ordered (proxy → gateway), pinned
to 0.1.1, default-OFF gate flipped via slot values, install/upgrade
disableWait per session-2026-04-30 architectural decision.
- clusters/omantel.omani.works/bootstrap-kit/* slots mirror the same
shape with omantel.biz hostnames matching the live HTTPRoutes on
console.omantel.biz / auth.omantel.biz.
API: shells/issue handler (matrix-canonical URL surface)
--------------------------------------------------------
- POST /api/v1/sovereigns/{id}/shells/issue?namespace=&pod=&container=
alias for the existing
POST /api/v1/sovereigns/{id}/k8s/exec/{ns}/{pod}/{container}/session
with matrix-canonical response fields (`sessionId`, `guacamoleUrl`,
`recordingPath`). Same business logic, same audit surface
(`guacamole-session-opened`), same RBAC gate (tier-developer or
higher). 6 test cases, all PASS under -race.
TCs that flip PASS in iter-8
-----------------------------
- TC-228: POST /shells/issue → sessionId + guacamoleUrl + recordingPath
- TC-230: kubectl get deploy guacd guacamole-server -n catalyst-system
- TC-236: kubectl get ds k8s-ws-proxy -n catalyst-system
- TC-237: kubectl logs ds/k8s-ws-proxy → "listening"
- TC-245: viewer-cookie POST /shells/issue → 403
- TC-246: operator-cookie POST /shells/issue → 200 sessionId
Per feedback_no_mvp_no_workarounds.md: NO follow-up slices — every
gap Fix#36 confessed is closed in this PR. Per
feedback_machine_saturation_3rd_violation.md: CI-only build path,
no local docker.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(bootstrap-kit): move bp-k8s-ws-proxy + bp-guacamole to slots 51/52 (Fix#39 follow-up)
CI dependency-graph-audit caught a slot-number collision: slots 36-48
are reserved for the W2.K4 AI-runtime cohort (bp-stunner, bp-knative,
bp-kserve, bp-vllm, bp-llm-gateway, bp-anthropic-adapter, bp-bge,
bp-nemo-guardrails, bp-temporal, bp-openmeter, bp-livekit, bp-matrix,
bp-librechat) per scripts/expected-bootstrap-deps.yaml. Move the
exec-fan-out blueprints to slots 51/52 (post-W2.K4, pre-Phase-2 80+
slot range) and add their entries to the expected DAG.
- clusters/_template/bootstrap-kit/{36,37}-* → {51,52}-*
- clusters/omantel.omani.works/bootstrap-kit/{36,37}-* → {51,52}-*
- kustomization.yaml updates (both _template + omantel)
- scripts/expected-bootstrap-deps.yaml: declare slots 51/52 with full
dependsOn lists (bp-k8s-ws-proxy on cilium+sealed-secrets,
bp-guacamole on cilium+cert-manager+keycloak+sealed-secrets+
seaweedfs+k8s-ws-proxy)
scripts/check-bootstrap-deps.sh re-run: 0 drift, 0 cycles, 55
declared HRs, 42 present on disk, 13 deferred (W2.K1-K4).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>