diff --git a/WORK-RECORDS.md b/WORK-RECORDS.md index 6ff122b..fd31768 100644 --- a/WORK-RECORDS.md +++ b/WORK-RECORDS.md @@ -14,6 +14,7 @@ | workplan | ISSUE-WP-0004 | finished | — | workplans/ISSUE-WP-0004-align-with-work-record-canon.md | | workplan | ISSUE-WP-0005 | finished | — | workplans/ISSUE-WP-0005-connector-alignment-implementation.md | | workplan | ISSUE-WP-0006 | ready | — | workplans/ISSUE-WP-0006-forgejo-only-projection-boundary.md | +| workplan | ISSUE-WP-0007 | ready | — | workplans/ISSUE-WP-0007-rapp-issue-core-railiance01-migration.md | | task | T01 | done | — | workplans/ISSC-WP-0001-rename-and-task-ingestion.md | | task | T02 | done | — | workplans/ISSC-WP-0001-rename-and-task-ingestion.md | | task | T03 | done | — | workplans/ISSC-WP-0001-rename-and-task-ingestion.md | @@ -46,3 +47,10 @@ | task | ISSUE-WP-0006-T02 | todo | — | workplans/ISSUE-WP-0006-forgejo-only-projection-boundary.md | | task | ISSUE-WP-0006-T03 | todo | — | workplans/ISSUE-WP-0006-forgejo-only-projection-boundary.md | | task | ISSUE-WP-0006-T04 | todo | — | workplans/ISSUE-WP-0006-forgejo-only-projection-boundary.md | +| task | ISSUE-WP-0007-T00 | done | — | workplans/ISSUE-WP-0007-rapp-issue-core-railiance01-migration.md | +| task | ISSUE-WP-0007-T01 | done | — | workplans/ISSUE-WP-0007-rapp-issue-core-railiance01-migration.md | +| task | ISSUE-WP-0007-T02 | todo | — | workplans/ISSUE-WP-0007-rapp-issue-core-railiance01-migration.md | +| task | ISSUE-WP-0007-T03 | todo | — | workplans/ISSUE-WP-0007-rapp-issue-core-railiance01-migration.md | +| task | ISSUE-WP-0007-T04 | todo | — | workplans/ISSUE-WP-0007-rapp-issue-core-railiance01-migration.md | +| task | ISSUE-WP-0007-T05 | todo | — | workplans/ISSUE-WP-0007-rapp-issue-core-railiance01-migration.md | +| task | ISSUE-WP-0007-T06 | todo | — | workplans/ISSUE-WP-0007-rapp-issue-core-railiance01-migration.md | diff --git a/history/2026-08-19-wp-0003-topology-correction.md b/history/2026-08-19-wp-0003-topology-correction.md new file mode 100644 index 0000000..23ce4b8 --- /dev/null +++ b/history/2026-08-19-wp-0003-topology-correction.md @@ -0,0 +1,24 @@ +# WP-0003 topology correction — 2026-08-19 + +ISSUE-WP-0003 deployed and verified issue-core, but its opening narrative +misidentified the target cluster. Its own 2026-07-02 completion note records +the corrected topology: + +- ArgoCD, the `issue-core` namespace, Service, ExternalSecret, and Deployment + were on the CoulombCore k3s cluster. +- The real railiance01 cluster ran activity-core and reached issue-core through + `actcore-issue-core-bridge` plus two ops-bridge forwards via the workstation. +- An authenticated activity-core-shaped request traversed that path and created + external issue 176, so WP-0003's functional proof remains valid for the + historical deployment. + +The 2026-08-19 observation that railiance01 has an empty `issue-core` namespace +and no ArgoCD is therefore not evidence that a railiance01 workload was pruned +or silently lost. The workload was never directly deployed there. The defect +was the workplan's stale opening summary and title after its later topology +correction. + +ISSUE-WP-0007 supersedes that topology. It keeps the reusable container, +secret, health, and authenticated-ingestion evidence while moving runtime +packaging into `rapp-issue-core` and placing the service directly on +`reef-railiance` / railiance01. diff --git a/workplans/ISSUE-WP-0003-railiance01-deployment.md b/workplans/ISSUE-WP-0003-railiance01-deployment.md index 089c4e1..90f532a 100644 --- a/workplans/ISSUE-WP-0003-railiance01-deployment.md +++ b/workplans/ISSUE-WP-0003-railiance01-deployment.md @@ -1,7 +1,7 @@ --- id: ISSUE-WP-0003 type: workplan -title: "Deploy issue-core as a service on railiance01 (ArgoCD GitOps pilot)" +title: "Historical CoulombCore deployment and railiance01 bridge (initially mislabeled as railiance01 GitOps)" domain: infotech repo: issue-core status: finished @@ -14,6 +14,17 @@ state_hub_workstream_id: "896ace77-21b3-450b-8fb7-254aefc8c570" # Deploy issue-core as a service on railiance01 (ArgoCD GitOps pilot) +> **Historical topology correction (2026-08-19):** This workplan is finished +> because it did deploy and prove issue-core, but the Deployment and ArgoCD +> Application were on **CoulombCore**, not railiance01. The real railiance01 +> consumed the service through the two-hop ops-bridge lane documented in the +> 2026-07-02 completion section. Railiance01 currently has an empty `issue-core` +> namespace and no ArgoCD. See +> `history/2026-08-19-wp-0003-topology-correction.md` and ISSUE-WP-0007 for the +> direct railiance01 migration. The paragraphs below are retained as historical +> evidence; unqualified "railiance01 cluster" claims refer to the mistaken +> topology understanding at the time. + `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 diff --git a/workplans/ISSUE-WP-0007-rapp-issue-core-railiance01-migration.md b/workplans/ISSUE-WP-0007-rapp-issue-core-railiance01-migration.md index 15f36fe..f8a1b9d 100644 --- a/workplans/ISSUE-WP-0007-rapp-issue-core-railiance01-migration.md +++ b/workplans/ISSUE-WP-0007-rapp-issue-core-railiance01-migration.md @@ -4,17 +4,25 @@ type: workplan title: "rapp-issue-core: move the runtime off CoulombCore onto railiance01" domain: infotech repo: issue-core -status: proposed -owner: unassigned +status: ready +owner: codex +lane: yellow topic_slug: issue-core priority: high created: "2026-08-19" updated: "2026-08-19" +reviewed_at: "2026-08-19" +quality_dor: DoR-Ok +quality_dor_at: "2026-08-19" +quality_dor_by: codex +quality_dor_note: "Goal, ownership, task order, dependencies, safety gates, and verification signals reviewed against the issue-core repo and current rapp family." depends_on: [] related: - ISSUE-WP-0003 + - ACTIVITY-WP-0023 - RMGR-WP-0006 - RMGR-WP-0007 +state_hub_workstream_id: "a2bc717a-64cf-45fa-8a9d-59d3bc9e96c7" --- # ISSUE-WP-0007 — rapp-issue-core: move the runtime onto railiance01 @@ -26,11 +34,13 @@ workstation's `18765` to railiance01, so railiance01 reaches issue-core *through a laptop* that is forwarding to CoulombCore. When CoulombCore goes, issue-core goes with it, and deleting the tunnel is not a migration. -## Start here: ISSUE-WP-0003 says this is already done. It is not. +## Start here: what ISSUE-WP-0003 actually proved -`ISSUE-WP-0003` is `status: finished` and states that "the railiance01 cluster -now reconciles `issue-core` through ArgoCD; External Secrets Operator reads the -OpenBao-backed runtime Secret and the Deployment is live on port 8765." +`ISSUE-WP-0003` is `status: finished` and its opening summary incorrectly says +that railiance01 reconciles `issue-core` through ArgoCD. Its own 2026-07-02 +completion section records the topology correction: the Deployment and ArgoCD +Application were on **CoulombCore**, while railiance01 reached them through the +two-hop ops-bridge lane. Checked on 2026-08-19 against the railiance01 cluster (`~/.kube/config-railiance01`, bridge tunnel `k3s-api-railiance01`, local @@ -42,14 +52,11 @@ Checked on 2026-08-19 against the railiance01 cluster | Reconciled by ArgoCD | **No ArgoCD** — the cluster has no `applications` resource type | | issue-core serving | Serving from **CoulombCore**: `-L 18765:10.43.103.154:8765`, `/healthz` → `{"status":"ok","version":"0.2.1"}` | -Whatever was stood up under WP-0003 is gone — most plausibly the railiance01 -cluster was rebuilt without it, since ArgoCD itself is absent. **Task T00 is to -establish what actually happened before rebuilding**, because if the deployment -was lost silently once it will be lost silently again, and a GitOps controller -that no longer exists is a different starting point than one that drifted. - -Do not treat WP-0003 as prior art to resume. Treat it as a record that needs -correcting once this workplan establishes the truth. +No railiance01 deployment was silently lost: the first deployment landed on the +wrong cluster and was then deliberately bridged to railiance01. The correction +is recorded in `history/2026-08-19-wp-0003-topology-correction.md` and at the +top of WP-0003. Treat its container, secret, service, and authenticated-ingest +evidence as prior art, but do not resume its ArgoCD topology. ## Why a `rapp-` wrapper rather than `k8s/railiance/` in this repo @@ -79,8 +86,9 @@ rmgr rapp validate --path ../rapp-issue-core --family-root .. rmgr rapp place --path ../rapp-issue-core --reef reef-railiance ``` -`--rail`, `--classification`, `--criticality`, and `--package-type` are -decisions, not defaults to accept blindly — settle them in T01. See +The reviewed values for this workload are `rail-kubernetes`, +`manifest-managed-platform-service`, `confidential`, and `high`. It remains a +private cluster service. See `repo-manager/docs/RailianceAppDeploymentGuide.md` (RMGR-WP-0006) and `RMGR-WP-0007` (greenfield rapp wrap efficiency). @@ -95,107 +103,184 @@ Migration is not done when a pod is Running. These reach issue-core today: are retired by this work; the second one should not be recreated in any form. - Anything reading `http://127.0.0.1:18765` on the workstation. -## Tasks +## Scope and human gate + +In scope: create and register `rapp-issue-core`; transfer the runtime package; +deploy it privately on railiance01; prove health, auth, Forgejo creation, +failure, and rollback; cut optional REST consumers over; then remove the legacy +bridge and tunnels. + +Out of scope: changing issue-core domain behaviour, adding Postgres, selecting +Knative, granting public exposure, changing activity-core's fleet-wide default +away from State Hub, or storing secret values in repo/Hub evidence. + +This is a yellow-lane production migration. T02/T03 are reversible file work. +The T04 live cluster apply and the T05 removal of bridge/tunnel infrastructure +require explicit implementation authorization; tunnel removal additionally +requires the recorded direct-path 201 gate. + +## T00 — Correct the historical topology record ```task id: ISSUE-WP-0007-T00 -status: todo +status: done priority: high +state_hub_task_id: "a195fe94-0231-4dd8-b75e-94f50fec86bc" ``` -**Establish what happened to the WP-0003 deployment.** Before rebuilding: -was ArgoCD removed deliberately, was the cluster rebuilt, or did the -Application drift and get pruned? Check railiance01 cluster history, the -`issue-core` namespace's remaining objects, and the OpenBao-backed -ExternalSecret referenced by WP-0003. Record the finding, and correct -`ISSUE-WP-0003` — a workplan asserting a production deployment that does not -exist will mislead the next reader exactly as it misled this one. +**Correct the WP-0003 topology record.** Done 2026-08-19. WP-0003's own +completion evidence shows that ArgoCD and the `issue-core` Deployment were on +CoulombCore, not railiance01; railiance01 consumed the service through a +two-hop bridge. Added a prominent correction to WP-0003 and recorded the +finding in `history/2026-08-19-wp-0003-topology-correction.md`. This was a +recording/topology error, not evidence of a railiance01 workload being pruned. -Deliverable: a short `history/` note. If the cause turns out to be a -platform-side defect rather than an issue-core one, route it to `risk-nexus` -as a finding rather than absorbing it here. +## T01 — Settle the packaging decisions ```task id: ISSUE-WP-0007-T01 -status: todo +status: done priority: high +state_hub_task_id: "2ab2dd49-1c69-4f8e-a807-ce078d2899ce" ``` -**Settle the packaging decisions.** `--rail` (`rail-kubernetes` vs -`rail-knative`), `--package-type`, `--classification`, `--criticality`, and -whether issue-core needs `--dedicated-postgres` or consumes `rapp-postgres` as -a consumer (it has a database; check which pattern the other rapps that need -one actually use). Decide against the existing `k8s/railiance/` manifests so -the wrapper starts from something real. +**Settle the packaging decisions.** Done 2026-08-19 against the current repo, +the live rapp family, and `RailianceAppDeploymentGuide.md`: + +- primary rail: `rail-kubernetes` — this is a long-running private API; it has + no request-activation, scale-to-zero, or revision-traffic requirement; +- package type: `manifest-managed-platform-service` — absorb the current + Kustomize manifests rather than inventing a Helm chart; +- data classification: `confidential` — issue titles/bodies and mapping + metadata may contain internal work context; +- criticality: `high` — external tracker projection fails when it is down, but + the file/State-Hub work-record spine continues; +- database: **none for the production wrapper** — the production backend is + Forgejo; SQLite is an optional offline/local backend, so do not pass + `--dedicated-postgres` and remove any generated Postgres-consumer draft; +- exposure: private; no Ingress or public grant. + +Reviewed scaffold command: + +```bash +UV_CACHE_DIR=/tmp/issue-core-rmgr-cache uv run --directory ../repo-manager \ + rmgr rapp wrap --path ../rapp-issue-core --app issue-core \ + --ownership-repo issue-core --from-app ../issue-core \ + --rail rail-kubernetes \ + --package-type manifest-managed-platform-service \ + --classification confidential --criticality high \ + --purpose "Package and operate the issue-core external-tracker connector on Railiance." +``` + +## T02 — Scaffold and register rapp-issue-core ```task id: ISSUE-WP-0007-T02 status: todo priority: high +state_hub_task_id: "e0427de0-dfac-4848-ba2d-1421167eb704" ``` **Scaffold `rapp-issue-core` via `rmgr rapp wrap`,** then -`rmgr rapp validate --family-root ..`. Do not hand-author the layout; the -validator encodes the family conventions and will reject a bespoke tree. -Register the new repo the normal way (write the files, commit, run the -consistency check) rather than by hand. +`rmgr rapp validate --path ../rapp-issue-core --family-root ..`. Remove the +generated Postgres-consumer draft because this deployment uses Forgejo, then +revalidate. Do not hand-author the baseline layout; the validator encodes the +family conventions and will reject a bespoke tree. Register the new repo the +normal file-first way and run its consistency check rather than creating Hub +records by hand. + +## T03 — Transfer the runtime package ```task id: ISSUE-WP-0007-T03 status: todo priority: high +state_hub_task_id: "d6e5e2ac-7f42-412f-8143-91531f5155e8" ``` -**Port the runtime.** Move `Dockerfile` / image build and the `k8s/railiance/` -tree into the wrapper's shape: manifests, secret references (OpenBao-backed -ExternalSecret — custody stays with the platform, never in this repo), -NetworkPolicy, Service. Image `0.2.1` is what is serving today; decide whether -to rebuild or promote the existing digest. +**Port the runtime package.** Keep `Dockerfile`, `docker-entrypoint.sh`, source, +tests, and `.forgejo/workflows/image.yaml` in `issue-core`; the app repo builds +and publishes the image. Move `k8s/railiance/` into the wrapper's manifest +shape, including the private Service, ServiceAccount, default-deny plus explicit +NetworkPolicy, and OpenBao-backed secret references. Pin a Forgejo OCI image by +immutable digest; do not reuse the retired Gitea registry tag as the release +contract. -`issue-core` keeps its domain code and loses its deployment artifacts. That -deletion is part of the task, not a follow-up — two sources of deployment truth -is the failure this split exists to prevent. +Delete `issue-core/k8s/railiance/` and retire `docs/argocd-gitops.md` only after +the wrapper contains an equivalent, validated runtime contract and retained +handoff. Two active sources of deployment truth are not allowed. + +## T04 — Place, deploy, and prove the direct service ```task id: ISSUE-WP-0007-T04 status: todo priority: high +state_hub_task_id: "21974fbd-4962-4732-b407-c531bb2ebfe6" ``` -**Deploy to railiance01 and prove it.** `rmgr rapp place --reef reef-railiance`, -then live evidence in the wrapper: cold start, `/healthz` 200 from *inside* the -cluster (not through a laptop forward), dependency-failure behaviour, and -rollback. Follow `rapp-qonto/tools/verify_live.sh` as the shape — reversible, -secret-free. +**Place, deploy, and prove it on railiance01.** Run `rmgr rapp place --path +../rapp-issue-core --reef reef-railiance --family-root ..`, then deploy through +the wrapper's reviewed apply surface. Credential custody remains in OpenBao: +route `ISSUE_CORE_API_KEY` through catalog `issue-core-ingestion-api-key` and +route the Forgejo PAT through the concrete platform/OpenBao lane (never log or +commit either value). + +Record secret-free live evidence in the wrapper for: rollout and Ready state; +image digest match; `/healthz` 200 from inside the cluster; unauthenticated +`POST /issues/` rejected; authenticated controlled `POST /issues/` returning +**201 through `forgejo-inbox`**; dependency failure returning a bounded 503; +NetworkPolicy presence; and rollback to the previous immutable digest. Follow +the reversible `rapp-qonto/tools/verify_live.sh` evidence style. Evidence that the service answers only via an ops-bridge tunnel does not count. That is the condition being retired. +## T05 — Cut consumers over and retire tunnels + ```task id: ISSUE-WP-0007-T05 status: todo priority: high +state_hub_task_id: "3fdbd9ab-3e3f-4ac0-8763-77278a1cc6e6" ``` -**Cut consumers over, then retire the tunnels.** Point activity-core's -`IssueSink` at the in-cluster address; ask ops-warden to update catalog id -`activity-core-issue-sink` if the routing pointer changes. Only once consumers -are on the new address, ask ops-bridge to remove `issue-core-coulombcore` and +**Cut consumers over, then retire the tunnels.** Point activity-core's optional +REST `IssueSink` endpoint directly at the new in-cluster Service and remove its +bridge Deployment/Service. Keep the fleet default `ISSUE_SINK_TYPE=state-hub`; +`rest` remains an explicit external-projection opt-in, not a global cutover. +Prove one controlled activity-core-shaped request returns 201 before asking +ops-warden to update catalog id `activity-core-issue-sink`. + +Inventory any other consumers of workstation port `18765`. Only once they are +cut over, ask ops-bridge to remove `issue-core-coulombcore` and `issue-core-railiance01` from `~/.config/bridge/tunnels.yaml`. Order matters: removing the tunnels first takes issue-core down for everyone still pointed at `127.0.0.1:18765`. +## T06 — Close out and notify dependants + ```task id: ISSUE-WP-0007-T06 status: todo priority: medium +state_hub_task_id: "668e37dc-8ebe-46cc-9a27-905440b1240c" ``` -**Close out.** Update `SCOPE.md` and `WORK-RECORDS.md`; correct `ISSUE-WP-0003` -per T00; tell ops-warden and ops-bridge that CoulombCore has one fewer -dependency. Remaining CoulombCore services after this: `core-hub-staging` and -`inter-hub`. +**Close out.** Update `SCOPE.md`, retire the obsolete ArgoCD runbook, sync both +repos' work records, and tell activity-core, ops-warden, and ops-bridge that the +direct Service is authoritative and CoulombCore has one fewer dependency. +Remaining CoulombCore services after this: `core-hub-staging` and `inter-hub`. + +## Implementation order and gates + +1. T02 may create/register the wrapper, but does not bind compute or apply. +2. T03 must leave a schema-valid, digest-pinned, secret-free runtime package. +3. T04 binds and deploys only after T03 validation and the OpenBao references + are confirmed; its 201 smoke is the promotion gate. +4. T05 changes consumers only after T04; tunnel retirement is last. +5. T06 closes only after direct-path evidence and tunnel removal are recorded. ## Notes for whoever picks this up @@ -205,6 +290,4 @@ dependency. Remaining CoulombCore services after this: `core-hub-staging` and (tunnel `k3s-api-railiance01`, local `16444`). There is no CoulombCore kubeconfig any more — its `k3s-api` tunnel was removed on 2026-08-19, so inspecting the *current* deployment needs that tunnel restored first. -- This workplan was drafted from outside issue-core (during ops-warden's - CoulombCore retirement sweep). The tasks are stated as findings and decisions - rather than a fixed design, because the owning repo should make the calls. +- Reviewed 2026-08-19 in issue-core and promoted from `proposed` to `ready`.