Arch pivot: every o2r layer ships as an isolated unit (pkg + chart + container) published from this repo #45

Closed
opened 2026-06-02 23:05:31 +00:00 by coilysiren · 5 comments
Owner

Arch pivot: every layer ships as an isolated unit, published from inside this repo

Each o2r layer should be installable on its own as all three artifact types, published from otel-a2a-relay itself:

  • Python package - already done. core (v0.3.0), channels (v0.1.0), arize_phoenix (v0.3.0), tempo_grafana (v0.3.0) are independently versioned, publishable workspace members.
  • Helm chart - none exist today. One chart per layer (not one mono-chart).
  • Docker container - none exist today. The current */docker/docker-compose.yml files only pull upstream images (phoenix/tempo/grafana); we need Dockerfiles that build o2r's own per-layer images.

Supersedes / reverses prior decisions

  • Supersedes #25 (closed) - that scoped one Helm chart for the whole system. This wants per-layer isolated charts instead.
  • Reverses the deploy-repo split - README ## Deploy and #25 put the Dockerfile + Helm chart + manifests in a separate repo (otel-a2a-relay-deploy). Decision (Kai, 2026-06-02): fold it back in. Dockerfiles + per-layer charts live here and publish from here; otel-a2a-relay-deploy gets deprecated/retired. Main repo owns all three artifact types end to end. README ## Deploy needs rewriting to match.

Layers in scope

core (relay/protocol + the relay service itself), channels (Agent Channel, Postgres-backed), arize_phoenix, tempo_grafana.

Hard dependency - registry sidequest

Container publish is blocked until there's a Docker registry to publish to. Sidequest: stand up a container registry on kai-server (file as its own issue, sequence it first for the docker leg). PyPI/package publish and Helm chart packaging are not blocked by this.

The "otel viewer plugins" system is still WIP; per-layer packaging should leave room for it but it is not a blocker here.

Acceptance (rough)

  • Each layer has: published python package (done), a Dockerfile producing a per-layer image pushed to the kai-server registry, and a per-layer Helm chart.
  • A publish pipeline (CI) covers all three artifact types from this repo.
  • README ## Deploy rewritten; otel-a2a-relay-deploy deprecation noted.
## Arch pivot: every layer ships as an isolated unit, published from inside this repo Each o2r layer should be installable on its own as **all three** artifact types, published from `otel-a2a-relay` itself: - **Python package** - already done. `core` (v0.3.0), `channels` (v0.1.0), `arize_phoenix` (v0.3.0), `tempo_grafana` (v0.3.0) are independently versioned, publishable workspace members. - **Helm chart** - none exist today. One chart per layer (not one mono-chart). - **Docker container** - none exist today. The current `*/docker/docker-compose.yml` files only pull upstream images (phoenix/tempo/grafana); we need Dockerfiles that build o2r's own per-layer images. ### Supersedes / reverses prior decisions - **Supersedes #25** (closed) - that scoped *one* Helm chart for the whole system. This wants **per-layer** isolated charts instead. - **Reverses the deploy-repo split** - README `## Deploy` and #25 put the Dockerfile + Helm chart + manifests in a separate repo (`otel-a2a-relay-deploy`). Decision (Kai, 2026-06-02): **fold it back in.** Dockerfiles + per-layer charts live here and publish from here; `otel-a2a-relay-deploy` gets deprecated/retired. Main repo owns all three artifact types end to end. README `## Deploy` needs rewriting to match. ### Layers in scope `core` (relay/protocol + the relay service itself), `channels` (Agent Channel, Postgres-backed), `arize_phoenix`, `tempo_grafana`. ### Hard dependency - registry sidequest Container publish is **blocked** until there's a Docker registry to publish to. Sidequest: stand up a container registry on **kai-server** (file as its own issue, sequence it first for the docker leg). PyPI/package publish and Helm chart packaging are not blocked by this. ### Related - WIP The "otel viewer plugins" system is still WIP; per-layer packaging should leave room for it but it is not a blocker here. ### Acceptance (rough) - Each layer has: published python package (done), a Dockerfile producing a per-layer image pushed to the kai-server registry, and a per-layer Helm chart. - A publish pipeline (CI) covers all three artifact types from this repo. - README `## Deploy` rewritten; `otel-a2a-relay-deploy` deprecation noted.
Author
Owner

Correction: the registry sidequest is largely already done

The body flags container publish as blocked on "stand up a registry on kai-server." That's mostly already solved. coilyco-flight-deck/infrastructure ships an in-cluster OCI registry, committed in feat(registry): in-cluster OCI registry for GitHub-free deploys:

  • Manifest: infrastructure/deploy/registry.yml - namespace registry, NodePort 30500 -> registry pod :5000, 20Gi local-path PVC pinned to kai-server.
  • Address (no DNS/TLS): 192.168.0.194:30500 (RFC1918 LAN IP, hardcode-safe). Insecure http; containerd told via /etc/rancher/k3s/registries.yaml, runner DinD via --insecure-registry.
  • Image ref scheme: 192.168.0.194:30500/<name-dashed>:<git-sha>.
  • Full bring-up runbook: infrastructure/docs/k3s-deploy-notes.md §11. The Forgejo runner (kai-desktop-tower-wsl node) builds + pushes; kai-server's containerd pulls.

So the docker leg is not blocked on a from-scratch registry. The remaining sidequest is only to verify the registry is live on the cluster (apply + the containerd insecure-mirror edit per the runbook) if it isn't already, then have o2r's per-layer Dockerfiles publish via a .forgejo/workflows/build-publish-deploy.yml following the documented per-repo pattern (scoped deployer ServiceAccount + kubeconfig secret per app namespace).

Net: drop the "build a registry" blocker; treat it as "adopt the existing homelab registry pattern."

### Correction: the registry sidequest is largely already done The body flags container publish as blocked on "stand up a registry on kai-server." That's mostly already solved. `coilyco-flight-deck/infrastructure` ships an in-cluster OCI registry, committed in `feat(registry): in-cluster OCI registry for GitHub-free deploys`: - Manifest: `infrastructure/deploy/registry.yml` - namespace `registry`, NodePort `30500` -> registry pod `:5000`, 20Gi local-path PVC pinned to kai-server. - Address (no DNS/TLS): `192.168.0.194:30500` (RFC1918 LAN IP, hardcode-safe). Insecure http; containerd told via `/etc/rancher/k3s/registries.yaml`, runner DinD via `--insecure-registry`. - Image ref scheme: `192.168.0.194:30500/<name-dashed>:<git-sha>`. - Full bring-up runbook: `infrastructure/docs/k3s-deploy-notes.md` §11. The Forgejo runner (kai-desktop-tower-wsl node) builds + pushes; kai-server's containerd pulls. **So the docker leg is not blocked on a from-scratch registry.** The remaining sidequest is only to *verify* the registry is live on the cluster (apply + the containerd insecure-mirror edit per the runbook) if it isn't already, then have o2r's per-layer Dockerfiles publish via a `.forgejo/workflows/build-publish-deploy.yml` following the documented per-repo pattern (scoped `deployer` ServiceAccount + kubeconfig secret per app namespace). Net: drop the "build a registry" blocker; treat it as "adopt the existing homelab registry pattern."
Author
Owner

Split into per-layer + cross-cutting issues

Registry confirmed live (kai-server, registry pod Running 5d11h) - the docker leg has a target. Breakdown:

Per-layer (each: container + chart; python pkg already ships):

  • #46 core - relay container + Helm chart (proving ground for the pipeline)
  • #47 channels - runnable app shim (no entrypoint today) + container + Postgres chart
  • #48 arize_phoenix - bootstrap container + Phoenix chart (+ provisioning Job)
  • #49 tempo_grafana - tooling container + Tempo/Prometheus/Grafana chart

Cross-cutting:

  • #50 shared build-publish-deploy pipeline (all three artifact types, path-filtered per layer) -> homelab registry
  • #51 rewrite README ## Deploy + retire otel-a2a-relay-deploy

Suggested sequence: #46 (prove the full pkg+chart+container loop on the simplest service) -> #50 (generalize the pipeline) -> #47/#48/#49 in parallel -> #51 cleanup last.

Open decisions to settle in #50: python publish target (PyPI vs private index) and Helm distribution (OCI in the same registry vs packaged-chart artifact).

### Split into per-layer + cross-cutting issues Registry confirmed **live** (kai-server, `registry` pod Running 5d11h) - the docker leg has a target. Breakdown: **Per-layer (each: container + chart; python pkg already ships):** - [ ] #46 core - relay container + Helm chart (proving ground for the pipeline) - [ ] #47 channels - runnable app shim (no entrypoint today) + container + Postgres chart - [ ] #48 arize_phoenix - bootstrap container + Phoenix chart (+ provisioning Job) - [ ] #49 tempo_grafana - tooling container + Tempo/Prometheus/Grafana chart **Cross-cutting:** - [ ] #50 shared `build-publish-deploy` pipeline (all three artifact types, path-filtered per layer) -> homelab registry - [ ] #51 rewrite README `## Deploy` + retire `otel-a2a-relay-deploy` **Suggested sequence:** #46 (prove the full pkg+chart+container loop on the simplest service) -> #50 (generalize the pipeline) -> #47/#48/#49 in parallel -> #51 cleanup last. **Open decisions to settle in #50:** python publish target (PyPI vs private index) and Helm distribution (OCI in the same registry vs packaged-chart artifact).
Author
Owner

Added: historical-data import + Phoenix deferred

  • #48 arize_phoenix - deferred (Kai, skip Phoenix this pass), closed.
  • #52 one-time import of historical Agent Channel data (channels + events) into the packaged channels Postgres. This is what "import historical o2r runs" meant - the live o2r channel list data, not Tempo traces. Depends on #47; one-time, not vendored.
### Added: historical-data import + Phoenix deferred - ~~#48 arize_phoenix~~ - **deferred** (Kai, skip Phoenix this pass), closed. - [ ] #52 one-time import of historical **Agent Channel** data (channels + events) into the packaged channels Postgres. This is what "import historical o2r runs" meant - the live `o2r channel list` data, not Tempo traces. Depends on #47; one-time, not vendored.
Author
Owner

Architecture locked (Kai, 2026-06-02)

Final shape after the in-tree-vs-separate-repo and GitOps decisions. This comment is the source of truth; earlier comments are superseded where they conflict.

Where artifacts live

  • Python packages - in-tree per layer (already shipping).
  • Helm charts - in-tree per layer (<layer>/chart/), versioned in lockstep with code, published as OCI artifacts to the kai-server registry. Not a separate chart repo.
  • Docker images - in-tree Dockerfile per layer, pushed to the kai-server registry (192.168.0.194:30500/<name>:<git-sha>).

GitOps split

  • coilyco-bridge/deploy becomes a pure GitOps repo on ArgoCD - app-of-apps + per-env values that reference the OCI-published charts. It does not hold chart templates or Dockerfiles.
  • Migration: the existing deploy/services/otel-a2a-relay/{Dockerfile,chart/} (scaffolded last night) moves in-tree into otel-a2a-relay (relay -> core/chart/, #46). deploy/services/otel-a2a-relay/deploy/ values + the ArgoCD Application stay in deploy. The "service repo stays unaware of deployment" philosophy in deploy's README is reversed - charts now live with code.

Cross-cutting requirements

  • Secure-by-default Postgres (#47): no exposed Service by default, NetworkPolicy to the app pod only, creds from a Secret. Opening access is explicit opt-in.
  • Exposure as a loosely-coupled plugin (#47): core charts are exposure-agnostic and run with no Tailscale present; tailnet reachability ships as an optional Tailscale plugin/subchart, off by default.
  • One-time channel-data import (#52): DB-level pg_dump of agent_channels + agent_channel_events only, into the packaged channels Postgres at cutover. Source store probed + verified.
  • Phoenix deferred (#48 closed). Lunch Money MCP / productization parked, document-only (#53).

Children

  • #46 core - migrate the existing relay chart + Dockerfile in-tree (head start: it already exists in deploy)
  • #47 channels - new chart, secure-by-default PG + tailscale-plugin exposure
  • #49 tempo_grafana - new chart
  • #50 shared build-publish-deploy pipeline -> OCI charts + images
  • #51 migrate deploy/services chart in-tree; strip deploy to pure GitOps; rewrite o2r README ## Deploy
  • #52 one-time channel-data import (depends on #47)
  • NEW (on coilyco-bridge/deploy) - stand up ArgoCD app-of-apps + learning ramp
  • #48 Phoenix deferred · #53 parked
## Architecture locked (Kai, 2026-06-02) Final shape after the in-tree-vs-separate-repo and GitOps decisions. This comment is the source of truth; earlier comments are superseded where they conflict. ### Where artifacts live - **Python packages** - in-tree per layer (already shipping). ✅ - **Helm charts** - **in-tree** per layer (`<layer>/chart/`), versioned in lockstep with code, **published as OCI artifacts** to the kai-server registry. Not a separate chart repo. - **Docker images** - in-tree Dockerfile per layer, pushed to the kai-server registry (`192.168.0.194:30500/<name>:<git-sha>`). ### GitOps split - **`coilyco-bridge/deploy`** becomes a **pure GitOps repo on ArgoCD** - app-of-apps + per-env values that reference the OCI-published charts. It does **not** hold chart templates or Dockerfiles. - **Migration:** the existing `deploy/services/otel-a2a-relay/{Dockerfile,chart/}` (scaffolded last night) **moves in-tree** into `otel-a2a-relay` (relay -> `core/chart/`, #46). `deploy/services/otel-a2a-relay/deploy/` values + the ArgoCD Application stay in `deploy`. The "service repo stays unaware of deployment" philosophy in deploy's README is **reversed** - charts now live with code. ### Cross-cutting requirements - **Secure-by-default Postgres** (#47): no exposed Service by default, NetworkPolicy to the app pod only, creds from a Secret. Opening access is explicit opt-in. - **Exposure as a loosely-coupled plugin** (#47): core charts are exposure-agnostic and run with no Tailscale present; tailnet reachability ships as an optional Tailscale plugin/subchart, off by default. - **One-time channel-data import** (#52): DB-level `pg_dump` of `agent_channels` + `agent_channel_events` only, into the packaged channels Postgres at cutover. Source store probed + verified. - **Phoenix deferred** (#48 closed). **Lunch Money MCP / productization parked, document-only** (#53). ### Children - [ ] #46 core - migrate the existing relay chart + Dockerfile in-tree (head start: it already exists in `deploy`) - [ ] #47 channels - new chart, secure-by-default PG + tailscale-plugin exposure - [ ] #49 tempo_grafana - new chart - [ ] #50 shared build-publish-deploy pipeline -> OCI charts + images - [ ] #51 migrate deploy/services chart in-tree; strip `deploy` to pure GitOps; rewrite o2r README `## Deploy` - [ ] #52 one-time channel-data import (depends on #47) - [ ] NEW (on `coilyco-bridge/deploy`) - stand up ArgoCD app-of-apps + learning ramp - ~~#48 Phoenix~~ deferred · #53 parked
coilysiren added
P3
and removed
P2
labels 2026-06-17 08:40:06 +00:00
Author
Owner

Closing. o2r is archived in the June 2026 surface reduction - an optional agent channel, unused autonomously. Handover doctrine moves to human-mediated.

Closing. o2r is archived in the June 2026 surface reduction - an optional agent channel, unused autonomously. Handover doctrine moves to human-mediated.
Commenting is not possible because the repository is archived.
No description provided.