Files
issue-core/workplans/ISSUE-WP-0003-railiance01-deployment.md
tegwick 19d4bc96df Normalize agent instructions and workplan frontmatter (STATE-WP-0067)
- Align agent files with on-disk workplan prefixes (infer from workplan ids)
- Set workplan domain to registered domain_slug; add topic_slug where applicable
- Repair frontmatter delimiter formatting; migrate legacy task status literals
- Regenerate AGENTS.md, CLAUDE.md, and .claude/rules from State Hub templates
2026-06-22 23:16:25 +02:00

11 KiB

id, type, title, domain, repo, status, owner, topic_slug, created, updated, state_hub_workstream_id
id type title domain repo status owner topic_slug created updated state_hub_workstream_id
ISSUE-WP-0003 workplan Deploy issue-core as a service on railiance01 (ArgoCD GitOps pilot) infotech issue-core active claude custodian 2026-06-19 2026-06-19 896ace77-21b3-450b-8fb7-254aefc8c570

Deploy issue-core as a service on railiance01 (ArgoCD GitOps pilot)

issue-core is the authoritative task-lifecycle manager and the REST ingestion target for activity-core's IssueSink. Deployment artifacts are on main (Dockerfile, docker-entrypoint.sh, k8s/railiance/); image gitea.coulomb.social/coulomb/issue-core:0.2.0 is built, pushed, and pullable. The railiance01 cluster still has no issue-core workload until T02 live ArgoCD bootstrap (RAILIANCE-WP-0004-T05) and T04 OpenBao secrets land.

This workplan stands up issue-core as a first-class in-cluster service on railiance01 via ArgoCD GitOps — making issue-core the cluster's first declarative Application and turning on the idle GitOps capability.

Current state (verified 2026-06-19)

  • Deployment artifacts in-repo: Dockerfile, docker-entrypoint.sh, and k8s/railiance/ (Kustomize: ExternalSecret, ConfigMap, Deployment, Service). Image builds locally; docker run + GET /healthz returns 200. Image pushed and pullable as gitea.coulomb.social/coulomb/issue-core:0.2.0 (digest sha256:153fbe43…). coulomb org packages are public — no imagePullSecret required per railiance-forge/docs/gitea-container-registry.md.
  • Dockerfile fix (2026-06-19): build arg renamed GITEA_PYPI_INDEX_URLARG PIP_INDEX_URL leaked into the build env and pip used Gitea as the sole index, so dependencies like click were not found.
  • railiance01 cluster: no issue-core namespace; no issue-core Deployment/Service/Pod in any namespace.
  • Dangling reference: activity-core/k8s/railiance/20-runtime.yaml sets ISSUE_CORE_URL: http://issue-core.issue-core.svc.cluster.local:8010 — a service that does not exist, on the wrong port (issue-core serves 8765) — with ISSUE_SINK_TYPE: "null" so emission is disabled. It is a placeholder.
  • Packaging precursor is done: ISSUE-WP-0002 published issue-core==0.2.0 to the Coulomb Gitea PyPI index.
  • ArgoCD is installed but unused: all 7 components healthy (~290d), but 0 Applications, 0 ApplicationSets, 0 registered git repos, only the stock default AppProject. No kind: Application manifests exist in any infra repo.
  • Existing deploy pattern is imperative (the path we are replacing for this service): local docker buildk3s ctr images import (side-load, no registry) → rsync manifests → kubectl apply (see activity-core/k8s/railiance/README.md).

Decisions

  • Deployment method = ArgoCD GitOps (operator decision 2026-06-19). issue-core is the pilot Application; the imperative side-load pattern is not used for this service.
  • ArgoCD bootstrap owned by railiance-platform (operator decision 2026-06-19). Platform owns repo registration, AppProject/app-of-apps conventions, and the External-Secrets/OpenBao plumbing. issue-core only contributes its Application manifest + workload manifests into the agreed GitOps source. T02 is therefore a cross-repo dependency, not issue-core work — see handoff to railiance-platform.
  • Backend = cluster Gitea (markitect) (operator decision 2026-06-19). Ingested tasks route to the existing Gitea backend; no new Postgres/PVC.
  • Secret management = OpenBao. ISSUE_CORE_API_KEY is a shared ingestion key injected from OpenBao on both issue-core and the activity-core worker. ops-warden does not vend it (see ~/ops-warden/wiki/playbooks/activity-core-issue-sink.md). Coordinate the canonical path with railiance-platform (issue-core-ingestion-api-key).
  • Image delivery = container registry, not side-load. GitOps requires a pullable image tag in a registry the cluster can reach (the Coulomb Gitea container registry); side-loading defeats declarative reproducibility.

Open questions

  • GitOps source repo. Resolved by railiance-platform as part of the bootstrap (T02 dependency): where issue-core's Application + manifests are expected to live (its own issue-core/k8s/ vs. a platform GitOps repo) and the AppProject/app-of-apps convention to follow.
  • Registry path & pull secret. Resolved: gitea.coulomb.social/coulomb/issue-core:<tag>; public org packages need no pull secret (see railiance-forge container-registry docs).

Container image published to a pullable registry

id: ISSUE-WP-0003-T01
status: done
priority: high
state_hub_task_id: "3723e896-3ec9-49b8-86f8-403993444da3"

Goal. A reproducible, registry-hosted image ArgoCD-managed pods can pull.

  • Add Dockerfile installing issue-core[api]>=0.2,<0.3 from the Gitea PyPI index (with explicit PyPI primary index). Entrypoint renders backends.json then issue serve --host 0.0.0.0 --port 8765.
  • Local build succeeds; docker run + GET /healthz returns 200.
  • Pushed gitea.coulomb.social/coulomb/issue-core:0.2.0; docker pull succeeds.
  • No cluster pull secret needed (coulomb org packages are public).
  • POST /issues/ smoke against a running deployment (deferred to T03/T04 cluster verification).

ArgoCD bootstrap (railiance-platform dependency) + issue-core Application

id: ISSUE-WP-0003-T02
status: wait
priority: high
state_hub_task_id: "9b199b1d-d3c0-4621-b8f8-58c376cbf878"

Owner split. ArgoCD bootstrap is railiance-platform's (operator decision 2026-06-19): repo registration in ArgoCD, AppProject/app-of-apps convention, and the agreed GitOps source layout. This task is wait on that handoff. issue-core's part is to contribute the Application manifest + workload manifests into the layout platform defines.

  • (railiance-platform) Register the GitOps source repo (repository Secret + creds); define AppProject for cluster services; publish the source-repo/path convention and sync policy.
  • (issue-core) Workload manifests in k8s/railiance/ on main per platform contract (docs/argocd-gitops.md). Tenant Application lives in railiance-platform/argocd/applications/issue-core.application.yaml.
  • (railiance-platform) RAILIANCE-WP-0004-T05 live bootstrap: register repo creds, deploy bootstrap, sync issue-core Application.
  • Verify: kubectl get applications -n argocd shows issue-core Synced/Healthy; ArgoCD reconciles a trivial manifest change.

Kubernetes manifests (namespace, Deployment, Service) in GitOps source

id: ISSUE-WP-0003-T03
status: progress
priority: high
state_hub_task_id: "38887dd6-0988-4ad1-bc6b-2a1b8839829f"

Goal. Declarative manifests in the GitOps source repo, synced by T02.

  • k8s/railiance/ Kustomize bundle (namespace via ArgoCD CreateNamespace=true).
  • Deployment: registry image tag 0.2.0; port 8765; /healthz probes; resource requests/limits; env from ExternalSecret (T04) and ConfigMap (T05).
  • Service: ClusterIP on 8765 as issue-core.issue-core.svc.cluster.local.
  • Verify: ArgoCD syncs the manifests; Pod Ready; /healthz 200 from a debug pod (blocked on T01 push + T02 bootstrap + T04 secrets).

OpenBao secret: ISSUE_CORE_API_KEY

id: ISSUE-WP-0003-T04
status: todo
priority: high
state_hub_task_id: "ad52527f-6222-4c11-9284-d8a3ed3b49ad"

Goal. The shared ingestion key delivered to both sides from OpenBao.

  • Provision ISSUE_CORE_API_KEY in OpenBao at the canonical path (coordinate with railiance-platform; catalog id issue-core-ingestion-api-key).
  • Deliver into the issue-core Deployment (T03) and the activity-core worker (T06) with the same value (External Secrets / Bao injector — match the cluster's established mechanism).
  • Never write the value to Git, manifests, State Hub, or logs.
  • Verify: both pods resolve a non-empty key; auth round-trip (401 without, 201 with).

In-cluster backend config (cluster Gitea / markitect)

id: ISSUE-WP-0003-T05
status: progress
priority: medium
state_hub_task_id: "10923f1e-050d-4f3e-980e-b061fef5f33a"

Goal. issue-core's backends.json inside the cluster points default at the cluster Gitea (markitect) backend.

  • ConfigMap issue-core-backends with in-cluster Gitea URL (gitea-http.default.svc.cluster.local:3000); token sentinel __FROM_ENV__.
  • docker-entrypoint.sh renders ~/.config/issue-tracker/backends.json from BACKENDS_TEMPLATE + GITEA_BACKEND_TOKEN at startup.
  • Verify: a POST /issues/ creates a real Gitea issue and returns issue_url (blocked on T04 secrets + in-cluster deployment).

Wire activity-core to the live service

id: ISSUE-WP-0003-T06
status: todo
priority: high
state_hub_task_id: "96b14cdb-364f-4eab-a80e-dd8b3859c694"

Goal. activity-core emits to the live issue-core Service.

  • Fix activity-core/k8s/railiance/20-runtime.yaml: ISSUE_CORE_URL port 8010 -> 8765; flip ISSUE_SINK_TYPE null -> rest once issue-core is Ready.
  • Inject ISSUE_CORE_API_KEY into the activity-core worker from the same OpenBao secret (T04).
  • Contract gap: issue-core requires triggering_event_id as a UUID; activity-core cron paths may send non-UUID keys (e.g. "scheduled"). Event-driven emission with real event UUIDs works (the str() guard in issue_sink.py, commit f05c56e, handles UUID objects). Align schemas before enabling rest for cron-triggered rules.
  • Verify: an activity-core run emits a task that lands in cluster Gitea via issue-core.

End-to-end verification + GitOps runbook

id: ISSUE-WP-0003-T07
status: todo
priority: medium
state_hub_task_id: "8d853b8e-cfca-441d-b817-0a29e37bd66e"

Goal. Confirm the deployed service is healthy and document the new path.

  • ArgoCD Application Synced/Healthy; issue-core Pod Ready; Service reachable cluster-internal.
  • activity-core → issue-core emission returns 201 and creates a Gitea issue.
  • Document the GitOps runbook (image build/push, ArgoCD sync, secret rotation, rollback) in docs/.
  • Emit an add_progress_event milestone to the hub on completion.

See also

  • ISSUE-WP-0002 — Gitea PyPI publication (packaging precursor, finished).
  • railiance-apps-WP-0004 I03 — issue-core packaging/image enablement notes.
  • railiance-forge — Gitea container registry docs.
  • activity-core/docs/issue-core-emission-boundary.md — emission contract.
  • activity-core/k8s/railiance/README.md — the imperative pattern being superseded for this service.
  • ~/ops-warden/wiki/playbooks/activity-core-issue-sink.md — key routing.