From 213e810cf82a47240548edc839aa4ab5278e7116 Mon Sep 17 00:00:00 2001 From: tegwick Date: Wed, 19 Aug 2026 23:41:57 +0200 Subject: [PATCH] Route issue-core directly on railiance01 --- docs/issue-core-emission-boundary.md | 22 +++-- k8s/railiance/20-runtime.yaml | 117 +-------------------------- k8s/railiance/README.md | 4 + 3 files changed, 16 insertions(+), 127 deletions(-) diff --git a/docs/issue-core-emission-boundary.md b/docs/issue-core-emission-boundary.md index b452da7..477b31f 100644 --- a/docs/issue-core-emission-boundary.md +++ b/docs/issue-core-emission-boundary.md @@ -78,23 +78,19 @@ activity-core. Railiance production uses `state-hub` unless an overlay explicitly sets `rest` for an experiment. -### Known production failure (2026-07-21, reconfirmed 2026-07-21 T06) — rest path +### Production direct path (verified 2026-08-19) -`POST /issues/` returns **HTTP 503**: +Railiance uses the private cluster-local endpoint: ```text -Failed to connect to backend 'forgejo-inbox': Failed to connect to Gitea API +http://issue-core.issue-core.svc.cluster.local:8765 ``` -(Historical error string from the Forgejo-compatible client library — the -deployed forge is **Forgejo**, not Gitea.) - -**Disposition (ACTIVITY-WP-0023-T06):** activity-core keeps global default -`state-hub` and does **not** flip production to `rest`. Path A is owned by -**issue-core**: rotate/fix `GITEA_BACKEND_TOKEN` (Forgejo backend PAT for the -forgejo-inbox connector — not the activity-core `ISSUE_CORE_API_KEY` -ingestion key). After issue-core proves `POST /issues/` → **201**, operators may -opt in per definition / overlay only (WP-0022). +`rapp-issue-core` verification proved authenticated create **201**, close +**200**, dependency failure **503**, and recovery **201/200** at immutable image +digest `sha256:a56c80ccbd1690bc0bcea384165b1967704f0fdbaf1c506ce1082f56190b92cf`. +activity-core still keeps the global default `state-hub`; a healthy transport +does not change the opt-in policy for external Forgejo projection. Internal scheduled automation should use **ops_run claim** (WP-0026), not wait on this rest path. @@ -103,7 +99,7 @@ Smoke from worker (does not change sink env): ```bash kubectl -n activity-core exec deploy/actcore-worker -- python -c ' -# valid IssueCore body → expect 201 when path A is healthy, else 503 forgejo-inbox +# valid IssueCore body → expect 201; close the controlled issue after the check ' ``` diff --git a/k8s/railiance/20-runtime.yaml b/k8s/railiance/20-runtime.yaml index 806c36e..0fe296b 100644 --- a/k8s/railiance/20-runtime.yaml +++ b/k8s/railiance/20-runtime.yaml @@ -14,9 +14,9 @@ data: LLM_CONNECT_URL: http://llm-connect.activity-core.svc.cluster.local:8080 LLM_CONNECT_TIMEOUT_SECONDS: "300" REPO_SCOPING_URL: http://repo-scoping.repo-scoping.svc.cluster.local:8020 - ISSUE_CORE_URL: http://actcore-issue-core-bridge.activity-core.svc.cluster.local:8765 - # ACTIVITY-WP-0021: state-hub until issue-core Forgejo PAT (GITEA_BACKEND_TOKEN) - # is rotated; switch back to "rest" after path A smoke returns 201. + ISSUE_CORE_URL: http://issue-core.issue-core.svc.cluster.local:8765 + # External Forgejo projection remains opt-in even though the direct path is + # healthy. Internal automation continues to use State Hub by default. ISSUE_SINK_TYPE: "state-hub" # ACTIVITY-WP-0026 / ACT-ADR-005 — claimable ops_run on emit (not Forgejo) OPS_RUN_QUEUE_ENABLED: "true" @@ -1030,117 +1030,6 @@ spec: persistentVolumeClaim: claimName: actcore-statehub-edge-outbox --- -apiVersion: v1 -kind: Service -metadata: - name: actcore-issue-core-bridge - namespace: activity-core - labels: - app.kubernetes.io/name: actcore-issue-core-bridge - app.kubernetes.io/part-of: activity-core -spec: - selector: - app.kubernetes.io/name: actcore-issue-core-bridge - ports: - - name: http - port: 8765 - targetPort: http ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - name: actcore-issue-core-bridge - namespace: activity-core - labels: - app.kubernetes.io/name: actcore-issue-core-bridge - app.kubernetes.io/part-of: activity-core -spec: - replicas: 1 - selector: - matchLabels: - app.kubernetes.io/name: actcore-issue-core-bridge - template: - metadata: - labels: - app.kubernetes.io/name: actcore-issue-core-bridge - app.kubernetes.io/part-of: activity-core - spec: - hostNetwork: true - dnsPolicy: ClusterFirstWithHostNet - containers: - - name: proxy - image: activity-core:railiance01-prod - imagePullPolicy: Never - ports: - - name: http - containerPort: 18081 - command: - - python - - -c - - | - from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer - from urllib.error import HTTPError, URLError - from urllib.request import Request, urlopen - - TARGET = "http://127.0.0.1:18765" - HOP_HEADERS = {"connection", "host", "keep-alive", "proxy-authenticate", - "proxy-authorization", "te", "trailers", - "transfer-encoding", "upgrade"} - - class Proxy(BaseHTTPRequestHandler): - def do_GET(self): - self._proxy() - - def do_POST(self): - self._proxy() - - def do_PATCH(self): - self._proxy() - - def _proxy(self): - length = int(self.headers.get("content-length", "0") or "0") - body = self.rfile.read(length) if length else None - headers = { - key: value - for key, value in self.headers.items() - if key.lower() not in HOP_HEADERS - } - request = Request( - TARGET + self.path, - data=body, - headers=headers, - method=self.command, - ) - try: - timeout = 360 if self.command == "POST" else 30 - with urlopen(request, timeout=timeout) as response: - payload = response.read() - self.send_response(response.status) - for key, value in response.headers.items(): - if key.lower() not in HOP_HEADERS: - self.send_header(key, value) - self.end_headers() - self.wfile.write(payload) - except HTTPError as exc: - payload = exc.read() - self.send_response(exc.code) - self.end_headers() - self.wfile.write(payload) - except URLError as exc: - self.send_response(502) - self.end_headers() - self.wfile.write(str(exc).encode()) - - ThreadingHTTPServer(("0.0.0.0", 18081), Proxy).serve_forever() - readinessProbe: - httpGet: - path: /healthz - port: http - initialDelaySeconds: 5 - periodSeconds: 10 - timeoutSeconds: 5 - failureThreshold: 6 ---- --- apiVersion: batch/v1 kind: Job diff --git a/k8s/railiance/README.md b/k8s/railiance/README.md index ccc1d43..c1bed99 100644 --- a/k8s/railiance/README.md +++ b/k8s/railiance/README.md @@ -33,6 +33,10 @@ issues). Set `rest` only for intentional issue-core projection when the backend is healthy. `ISSUE_CORE_API_KEY` and `FORGEJO_TOKEN` are synced from OpenBao into `actcore-runtime-secret` by ExternalSecrets. +`ISSUE_CORE_URL` uses the private cross-namespace Service directly: +`http://issue-core.issue-core.svc.cluster.local:8765`. The historical +host-network bridge and workstation tunnel are not part of this deployment. + **Ops run claim queue (ACTIVITY-WP-0026):** ConfigMap sets `OPS_RUN_QUEUE_ENABLED=true`. After image + migrate job (alembic **0007**), workers insert claimable `ops_runs` on emit. Full railiance checklist: