rapp-canned-prompts/workplans/RCP-WP-0002-first-deployment.md

162 lines
5.9 KiB
Markdown
Raw Normal View History

Package canned-prompts for Railiance Registers the repo with State Hub (agents / practice, prefix RCP-WP) and fills in the rapp shape. declarations/rapp.yaml declares a manifest-managed platform service owned by canned-prompts, bound to rail-kubernetes and reef-railiance, with rollout, smoke and rollback contracts. The image pin says `pending-publication` rather than carrying a placeholder digest. The image builds and was verified locally (canned-prompts CANP-WP-0006-T06) but has never been pushed, so no registry digest exists. A placeholder shaped like a real digest would be worse than a sentinel: it could be mistaken for something deployable. manifests/ follows the rapp-sbom-nexus shape: namespace labelled for the postgres client, external secrets from OpenBao, a migration Job, and the runtime Deployment with a ClusterIP-only Service, dedicated ServiceAccount and default-deny plus runtime NetworkPolicies. Three choices worth stating. Credentials arrive as mounted files, never env vars — an env var holding a password is visible in kubectl describe, in crash dumps, and to anything that can read /proc. Migrations run as a Job rather than at start-up, so a schema rollback stays separate from a code rollback and replicas do not race. Liveness points at /healthz, which checks only that the process is up: pointing it at a database-dependent path would restart every replica during a database blip. Egress is PostgreSQL and DNS only. A package arrives by publish; the registry never reaches out, so it is given no path to. tools/smoke.sh checks what only the cluster can answer and calls canned-prompts' service/tools/smoke.py for health and migration head, rather than holding a second opinion about whether the service is healthy. RCP-WP-0002 carries the two operator actions that block a first rollout — publishing the image and provisioning database roles — and records per-publisher identity as a decision belonging upstream, which this repo must not paper over with cluster configuration implying finer control than exists. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Bjefh8NUiEiahN4JLwoSKM Assistant: claude-code Assistant-Model: opus Assistant-Process: 388925@bnt-lap001 Assistant-Session: 3507023f-e0fd-4a1e-9d90-a0d4217d1502
2026-09-06 21:44:17 +02:00
---
id: RCP-WP-0002
type: workplan
title: "First deployment of canned-prompts on Railiance"
domain: agents
repo: rapp-canned-prompts
Publish the image, pin it by digest, and request the database RCP-WP-0002-T01 done. Published forgejo.coulomb.social/coulomb/canned-prompts:0.1.0 and pinned sha256:e0ded3c7fe25... in declarations/rapp.yaml and both manifests. Pinned by digest rather than tag: a tag can be moved, and live-image-digest-match would then pass against something that is no longer what this repo reviewed. Verified after the push by fetching the manifest back by digest rather than trusting the push output. readiness_state draft -> declared. Not deployed, so not `deployed`. T02 requested rather than performed. rapp-postgres now carries consumers/canned-prompts.yaml against its documented PostgresConsumer shape, and its agent has the request. `make provision-consumers`, which mints the OpenBao credentials, was deliberately not run: credential issuance belongs to that repo's operator, and running it from the consuming side would take a decision that is not this repo's, however available the script is. T03 and T04 move to wait behind it. Also corrected a check of my own: I briefly read the cluster list as lacking platform-pg-2 and suspected the manifests targeted a host that does not exist. That was my own truncated output. platform-pg-2 is present and healthy, and the postgres-client label matches what sbom-nexus actually carries in the cluster rather than only what its repo says. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Bjefh8NUiEiahN4JLwoSKM Assistant: claude-code Assistant-Model: opus Assistant-Process: 388925@bnt-lap001 Assistant-Session: 3507023f-e0fd-4a1e-9d90-a0d4217d1502
2026-09-07 08:43:35 +02:00
status: active
Package canned-prompts for Railiance Registers the repo with State Hub (agents / practice, prefix RCP-WP) and fills in the rapp shape. declarations/rapp.yaml declares a manifest-managed platform service owned by canned-prompts, bound to rail-kubernetes and reef-railiance, with rollout, smoke and rollback contracts. The image pin says `pending-publication` rather than carrying a placeholder digest. The image builds and was verified locally (canned-prompts CANP-WP-0006-T06) but has never been pushed, so no registry digest exists. A placeholder shaped like a real digest would be worse than a sentinel: it could be mistaken for something deployable. manifests/ follows the rapp-sbom-nexus shape: namespace labelled for the postgres client, external secrets from OpenBao, a migration Job, and the runtime Deployment with a ClusterIP-only Service, dedicated ServiceAccount and default-deny plus runtime NetworkPolicies. Three choices worth stating. Credentials arrive as mounted files, never env vars — an env var holding a password is visible in kubectl describe, in crash dumps, and to anything that can read /proc. Migrations run as a Job rather than at start-up, so a schema rollback stays separate from a code rollback and replicas do not race. Liveness points at /healthz, which checks only that the process is up: pointing it at a database-dependent path would restart every replica during a database blip. Egress is PostgreSQL and DNS only. A package arrives by publish; the registry never reaches out, so it is given no path to. tools/smoke.sh checks what only the cluster can answer and calls canned-prompts' service/tools/smoke.py for health and migration head, rather than holding a second opinion about whether the service is healthy. RCP-WP-0002 carries the two operator actions that block a first rollout — publishing the image and provisioning database roles — and records per-publisher identity as a decision belonging upstream, which this repo must not paper over with cluster configuration implying finer control than exists. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Bjefh8NUiEiahN4JLwoSKM Assistant: claude-code Assistant-Model: opus Assistant-Process: 388925@bnt-lap001 Assistant-Session: 3507023f-e0fd-4a1e-9d90-a0d4217d1502
2026-09-06 21:44:17 +02:00
owner: codex
topic_slug: practice
created: "2026-09-06"
updated: "2026-09-06"
state_hub_workstream_id: "11874f32-ac36-5bb9-a0a5-e7a259f5972c"
---
# First deployment of canned-prompts on Railiance
The package is written and validated; what remains needs credentials and a
published image, which are operator actions rather than authoring ones.
`readiness_state` is `draft` and stays there until T04 produces evidence.
Topology is not readiness (ADR-0006): binding this rapp to a reef does not make
it deployed.
## Publish the image and pin its digest
```task
id: RCP-WP-0002-T01
Publish the image, pin it by digest, and request the database RCP-WP-0002-T01 done. Published forgejo.coulomb.social/coulomb/canned-prompts:0.1.0 and pinned sha256:e0ded3c7fe25... in declarations/rapp.yaml and both manifests. Pinned by digest rather than tag: a tag can be moved, and live-image-digest-match would then pass against something that is no longer what this repo reviewed. Verified after the push by fetching the manifest back by digest rather than trusting the push output. readiness_state draft -> declared. Not deployed, so not `deployed`. T02 requested rather than performed. rapp-postgres now carries consumers/canned-prompts.yaml against its documented PostgresConsumer shape, and its agent has the request. `make provision-consumers`, which mints the OpenBao credentials, was deliberately not run: credential issuance belongs to that repo's operator, and running it from the consuming side would take a decision that is not this repo's, however available the script is. T03 and T04 move to wait behind it. Also corrected a check of my own: I briefly read the cluster list as lacking platform-pg-2 and suspected the manifests targeted a host that does not exist. That was my own truncated output. platform-pg-2 is present and healthy, and the postgres-client label matches what sbom-nexus actually carries in the cluster rather than only what its repo says. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Bjefh8NUiEiahN4JLwoSKM Assistant: claude-code Assistant-Model: opus Assistant-Process: 388925@bnt-lap001 Assistant-Session: 3507023f-e0fd-4a1e-9d90-a0d4217d1502
2026-09-07 08:43:35 +02:00
status: done
Package canned-prompts for Railiance Registers the repo with State Hub (agents / practice, prefix RCP-WP) and fills in the rapp shape. declarations/rapp.yaml declares a manifest-managed platform service owned by canned-prompts, bound to rail-kubernetes and reef-railiance, with rollout, smoke and rollback contracts. The image pin says `pending-publication` rather than carrying a placeholder digest. The image builds and was verified locally (canned-prompts CANP-WP-0006-T06) but has never been pushed, so no registry digest exists. A placeholder shaped like a real digest would be worse than a sentinel: it could be mistaken for something deployable. manifests/ follows the rapp-sbom-nexus shape: namespace labelled for the postgres client, external secrets from OpenBao, a migration Job, and the runtime Deployment with a ClusterIP-only Service, dedicated ServiceAccount and default-deny plus runtime NetworkPolicies. Three choices worth stating. Credentials arrive as mounted files, never env vars — an env var holding a password is visible in kubectl describe, in crash dumps, and to anything that can read /proc. Migrations run as a Job rather than at start-up, so a schema rollback stays separate from a code rollback and replicas do not race. Liveness points at /healthz, which checks only that the process is up: pointing it at a database-dependent path would restart every replica during a database blip. Egress is PostgreSQL and DNS only. A package arrives by publish; the registry never reaches out, so it is given no path to. tools/smoke.sh checks what only the cluster can answer and calls canned-prompts' service/tools/smoke.py for health and migration head, rather than holding a second opinion about whether the service is healthy. RCP-WP-0002 carries the two operator actions that block a first rollout — publishing the image and provisioning database roles — and records per-publisher identity as a decision belonging upstream, which this repo must not paper over with cluster configuration implying finer control than exists. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Bjefh8NUiEiahN4JLwoSKM Assistant: claude-code Assistant-Model: opus Assistant-Process: 388925@bnt-lap001 Assistant-Session: 3507023f-e0fd-4a1e-9d90-a0d4217d1502
2026-09-06 21:44:17 +02:00
priority: high
state_hub_task_id: "3e7faf50-8fe9-5ef3-8a75-1d9e586d6c0f"
```
`declarations/rapp.yaml` carries `version: pending-publication`, and both
manifests carry a matching tag. This is deliberate: a placeholder shaped like a
real digest could be mistaken for something deployable, and a rapp that pins
nothing is a stub that tells the fleet tooling a deployment exists when none
does.
The image builds and was verified locally in `canned-prompts`
(`CANP-WP-0006-T06`): it starts non-root, all six service-level smoke checks
pass against the running container, and the reference CLI installs a package
from it over HTTP.
Publish the image, pin it by digest, and request the database RCP-WP-0002-T01 done. Published forgejo.coulomb.social/coulomb/canned-prompts:0.1.0 and pinned sha256:e0ded3c7fe25... in declarations/rapp.yaml and both manifests. Pinned by digest rather than tag: a tag can be moved, and live-image-digest-match would then pass against something that is no longer what this repo reviewed. Verified after the push by fetching the manifest back by digest rather than trusting the push output. readiness_state draft -> declared. Not deployed, so not `deployed`. T02 requested rather than performed. rapp-postgres now carries consumers/canned-prompts.yaml against its documented PostgresConsumer shape, and its agent has the request. `make provision-consumers`, which mints the OpenBao credentials, was deliberately not run: credential issuance belongs to that repo's operator, and running it from the consuming side would take a decision that is not this repo's, however available the script is. T03 and T04 move to wait behind it. Also corrected a check of my own: I briefly read the cluster list as lacking platform-pg-2 and suspected the manifests targeted a host that does not exist. That was my own truncated output. platform-pg-2 is present and healthy, and the postgres-client label matches what sbom-nexus actually carries in the cluster rather than only what its repo says. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Bjefh8NUiEiahN4JLwoSKM Assistant: claude-code Assistant-Model: opus Assistant-Process: 388925@bnt-lap001 Assistant-Session: 3507023f-e0fd-4a1e-9d90-a0d4217d1502
2026-09-07 08:43:35 +02:00
**Done, 2026-09-07.** Published as
`forgejo.coulomb.social/coulomb/canned-prompts:0.1.0` and pinned by **digest**
in the declaration and both manifests:
```
sha256:e0ded3c7fe2548c910445deaa31ec42e84f129a92aa324841e231a53fee1f123
```
Pinned by digest rather than tag deliberately: a tag can be moved, and
`live-image-digest-match` would then pass against something that is no longer
what this repo reviewed.
Verified before pushing — the image resolves a file-mounted credential, carries
the reference validator, and ships the migration scripts — and verified after,
by fetching the manifest back **by digest** rather than trusting the push
output. `readiness_state` moved `draft``declared`.
Package canned-prompts for Railiance Registers the repo with State Hub (agents / practice, prefix RCP-WP) and fills in the rapp shape. declarations/rapp.yaml declares a manifest-managed platform service owned by canned-prompts, bound to rail-kubernetes and reef-railiance, with rollout, smoke and rollback contracts. The image pin says `pending-publication` rather than carrying a placeholder digest. The image builds and was verified locally (canned-prompts CANP-WP-0006-T06) but has never been pushed, so no registry digest exists. A placeholder shaped like a real digest would be worse than a sentinel: it could be mistaken for something deployable. manifests/ follows the rapp-sbom-nexus shape: namespace labelled for the postgres client, external secrets from OpenBao, a migration Job, and the runtime Deployment with a ClusterIP-only Service, dedicated ServiceAccount and default-deny plus runtime NetworkPolicies. Three choices worth stating. Credentials arrive as mounted files, never env vars — an env var holding a password is visible in kubectl describe, in crash dumps, and to anything that can read /proc. Migrations run as a Job rather than at start-up, so a schema rollback stays separate from a code rollback and replicas do not race. Liveness points at /healthz, which checks only that the process is up: pointing it at a database-dependent path would restart every replica during a database blip. Egress is PostgreSQL and DNS only. A package arrives by publish; the registry never reaches out, so it is given no path to. tools/smoke.sh checks what only the cluster can answer and calls canned-prompts' service/tools/smoke.py for health and migration head, rather than holding a second opinion about whether the service is healthy. RCP-WP-0002 carries the two operator actions that block a first rollout — publishing the image and provisioning database roles — and records per-publisher identity as a decision belonging upstream, which this repo must not paper over with cluster configuration implying finer control than exists. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Bjefh8NUiEiahN4JLwoSKM Assistant: claude-code Assistant-Model: opus Assistant-Process: 388925@bnt-lap001 Assistant-Session: 3507023f-e0fd-4a1e-9d90-a0d4217d1502
2026-09-06 21:44:17 +02:00
## Provision database roles and credentials
```task
id: RCP-WP-0002-T02
Publish the image, pin it by digest, and request the database RCP-WP-0002-T01 done. Published forgejo.coulomb.social/coulomb/canned-prompts:0.1.0 and pinned sha256:e0ded3c7fe25... in declarations/rapp.yaml and both manifests. Pinned by digest rather than tag: a tag can be moved, and live-image-digest-match would then pass against something that is no longer what this repo reviewed. Verified after the push by fetching the manifest back by digest rather than trusting the push output. readiness_state draft -> declared. Not deployed, so not `deployed`. T02 requested rather than performed. rapp-postgres now carries consumers/canned-prompts.yaml against its documented PostgresConsumer shape, and its agent has the request. `make provision-consumers`, which mints the OpenBao credentials, was deliberately not run: credential issuance belongs to that repo's operator, and running it from the consuming side would take a decision that is not this repo's, however available the script is. T03 and T04 move to wait behind it. Also corrected a check of my own: I briefly read the cluster list as lacking platform-pg-2 and suspected the manifests targeted a host that does not exist. That was my own truncated output. platform-pg-2 is present and healthy, and the postgres-client label matches what sbom-nexus actually carries in the cluster rather than only what its repo says. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Bjefh8NUiEiahN4JLwoSKM Assistant: claude-code Assistant-Model: opus Assistant-Process: 388925@bnt-lap001 Assistant-Session: 3507023f-e0fd-4a1e-9d90-a0d4217d1502
2026-09-07 08:43:35 +02:00
status: wait
Package canned-prompts for Railiance Registers the repo with State Hub (agents / practice, prefix RCP-WP) and fills in the rapp shape. declarations/rapp.yaml declares a manifest-managed platform service owned by canned-prompts, bound to rail-kubernetes and reef-railiance, with rollout, smoke and rollback contracts. The image pin says `pending-publication` rather than carrying a placeholder digest. The image builds and was verified locally (canned-prompts CANP-WP-0006-T06) but has never been pushed, so no registry digest exists. A placeholder shaped like a real digest would be worse than a sentinel: it could be mistaken for something deployable. manifests/ follows the rapp-sbom-nexus shape: namespace labelled for the postgres client, external secrets from OpenBao, a migration Job, and the runtime Deployment with a ClusterIP-only Service, dedicated ServiceAccount and default-deny plus runtime NetworkPolicies. Three choices worth stating. Credentials arrive as mounted files, never env vars — an env var holding a password is visible in kubectl describe, in crash dumps, and to anything that can read /proc. Migrations run as a Job rather than at start-up, so a schema rollback stays separate from a code rollback and replicas do not race. Liveness points at /healthz, which checks only that the process is up: pointing it at a database-dependent path would restart every replica during a database blip. Egress is PostgreSQL and DNS only. A package arrives by publish; the registry never reaches out, so it is given no path to. tools/smoke.sh checks what only the cluster can answer and calls canned-prompts' service/tools/smoke.py for health and migration head, rather than holding a second opinion about whether the service is healthy. RCP-WP-0002 carries the two operator actions that block a first rollout — publishing the image and provisioning database roles — and records per-publisher identity as a decision belonging upstream, which this repo must not paper over with cluster configuration implying finer control than exists. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Bjefh8NUiEiahN4JLwoSKM Assistant: claude-code Assistant-Model: opus Assistant-Process: 388925@bnt-lap001 Assistant-Session: 3507023f-e0fd-4a1e-9d90-a0d4217d1502
2026-09-06 21:44:17 +02:00
priority: high
state_hub_task_id: "61f5cbd7-8fcf-5156-87da-57239ae55d8f"
```
Two roles, deliberately separate: a runtime role that reads and writes rows, and
a migration role that owns the schema. A service able to `ALTER` its own tables
at runtime turns any code defect into a schema defect.
Needed from `rapp-postgres` and the credential broker:
- database `canned_prompts` on `platform-pg-2`;
- `creds/canned-prompts-runtime` and `creds/canned-prompts-migration` in OpenBao
under the `database` path;
- the `openbao-canned-prompts-eso-token` secret in `external-secrets`.
`creds/canned-prompts-publish` is **optional**. Without it the service is
read-only, which is the correct posture until per-publisher identity exists —
not a misconfiguration to be worked around.
Publish the image, pin it by digest, and request the database RCP-WP-0002-T01 done. Published forgejo.coulomb.social/coulomb/canned-prompts:0.1.0 and pinned sha256:e0ded3c7fe25... in declarations/rapp.yaml and both manifests. Pinned by digest rather than tag: a tag can be moved, and live-image-digest-match would then pass against something that is no longer what this repo reviewed. Verified after the push by fetching the manifest back by digest rather than trusting the push output. readiness_state draft -> declared. Not deployed, so not `deployed`. T02 requested rather than performed. rapp-postgres now carries consumers/canned-prompts.yaml against its documented PostgresConsumer shape, and its agent has the request. `make provision-consumers`, which mints the OpenBao credentials, was deliberately not run: credential issuance belongs to that repo's operator, and running it from the consuming side would take a decision that is not this repo's, however available the script is. T03 and T04 move to wait behind it. Also corrected a check of my own: I briefly read the cluster list as lacking platform-pg-2 and suspected the manifests targeted a host that does not exist. That was my own truncated output. platform-pg-2 is present and healthy, and the postgres-client label matches what sbom-nexus actually carries in the cluster rather than only what its repo says. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Bjefh8NUiEiahN4JLwoSKM Assistant: claude-code Assistant-Model: opus Assistant-Process: 388925@bnt-lap001 Assistant-Session: 3507023f-e0fd-4a1e-9d90-a0d4217d1502
2026-09-07 08:43:35 +02:00
**Requested, 2026-09-07.** `rapp-postgres` now carries
`consumers/canned-prompts.yaml`, authored against its documented
`PostgresConsumer` shape, and its agent has the request in its inbox.
The declaration only. `make provision-consumers` — the step that actually mints
OpenBao credentials — was deliberately **not** run: credential issuance is
`rapp-postgres`' to perform, and running it from the consuming side would take a
decision that is not this repo's, however available the script happens to be.
Blocked here until those credentials exist. T03 and T04 are blocked behind it.
Package canned-prompts for Railiance Registers the repo with State Hub (agents / practice, prefix RCP-WP) and fills in the rapp shape. declarations/rapp.yaml declares a manifest-managed platform service owned by canned-prompts, bound to rail-kubernetes and reef-railiance, with rollout, smoke and rollback contracts. The image pin says `pending-publication` rather than carrying a placeholder digest. The image builds and was verified locally (canned-prompts CANP-WP-0006-T06) but has never been pushed, so no registry digest exists. A placeholder shaped like a real digest would be worse than a sentinel: it could be mistaken for something deployable. manifests/ follows the rapp-sbom-nexus shape: namespace labelled for the postgres client, external secrets from OpenBao, a migration Job, and the runtime Deployment with a ClusterIP-only Service, dedicated ServiceAccount and default-deny plus runtime NetworkPolicies. Three choices worth stating. Credentials arrive as mounted files, never env vars — an env var holding a password is visible in kubectl describe, in crash dumps, and to anything that can read /proc. Migrations run as a Job rather than at start-up, so a schema rollback stays separate from a code rollback and replicas do not race. Liveness points at /healthz, which checks only that the process is up: pointing it at a database-dependent path would restart every replica during a database blip. Egress is PostgreSQL and DNS only. A package arrives by publish; the registry never reaches out, so it is given no path to. tools/smoke.sh checks what only the cluster can answer and calls canned-prompts' service/tools/smoke.py for health and migration head, rather than holding a second opinion about whether the service is healthy. RCP-WP-0002 carries the two operator actions that block a first rollout — publishing the image and provisioning database roles — and records per-publisher identity as a decision belonging upstream, which this repo must not paper over with cluster configuration implying finer control than exists. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Bjefh8NUiEiahN4JLwoSKM Assistant: claude-code Assistant-Model: opus Assistant-Process: 388925@bnt-lap001 Assistant-Session: 3507023f-e0fd-4a1e-9d90-a0d4217d1502
2026-09-06 21:44:17 +02:00
## Apply and migrate
```task
id: RCP-WP-0002-T03
Publish the image, pin it by digest, and request the database RCP-WP-0002-T01 done. Published forgejo.coulomb.social/coulomb/canned-prompts:0.1.0 and pinned sha256:e0ded3c7fe25... in declarations/rapp.yaml and both manifests. Pinned by digest rather than tag: a tag can be moved, and live-image-digest-match would then pass against something that is no longer what this repo reviewed. Verified after the push by fetching the manifest back by digest rather than trusting the push output. readiness_state draft -> declared. Not deployed, so not `deployed`. T02 requested rather than performed. rapp-postgres now carries consumers/canned-prompts.yaml against its documented PostgresConsumer shape, and its agent has the request. `make provision-consumers`, which mints the OpenBao credentials, was deliberately not run: credential issuance belongs to that repo's operator, and running it from the consuming side would take a decision that is not this repo's, however available the script is. T03 and T04 move to wait behind it. Also corrected a check of my own: I briefly read the cluster list as lacking platform-pg-2 and suspected the manifests targeted a host that does not exist. That was my own truncated output. platform-pg-2 is present and healthy, and the postgres-client label matches what sbom-nexus actually carries in the cluster rather than only what its repo says. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Bjefh8NUiEiahN4JLwoSKM Assistant: claude-code Assistant-Model: opus Assistant-Process: 388925@bnt-lap001 Assistant-Session: 3507023f-e0fd-4a1e-9d90-a0d4217d1502
2026-09-07 08:43:35 +02:00
status: wait
Package canned-prompts for Railiance Registers the repo with State Hub (agents / practice, prefix RCP-WP) and fills in the rapp shape. declarations/rapp.yaml declares a manifest-managed platform service owned by canned-prompts, bound to rail-kubernetes and reef-railiance, with rollout, smoke and rollback contracts. The image pin says `pending-publication` rather than carrying a placeholder digest. The image builds and was verified locally (canned-prompts CANP-WP-0006-T06) but has never been pushed, so no registry digest exists. A placeholder shaped like a real digest would be worse than a sentinel: it could be mistaken for something deployable. manifests/ follows the rapp-sbom-nexus shape: namespace labelled for the postgres client, external secrets from OpenBao, a migration Job, and the runtime Deployment with a ClusterIP-only Service, dedicated ServiceAccount and default-deny plus runtime NetworkPolicies. Three choices worth stating. Credentials arrive as mounted files, never env vars — an env var holding a password is visible in kubectl describe, in crash dumps, and to anything that can read /proc. Migrations run as a Job rather than at start-up, so a schema rollback stays separate from a code rollback and replicas do not race. Liveness points at /healthz, which checks only that the process is up: pointing it at a database-dependent path would restart every replica during a database blip. Egress is PostgreSQL and DNS only. A package arrives by publish; the registry never reaches out, so it is given no path to. tools/smoke.sh checks what only the cluster can answer and calls canned-prompts' service/tools/smoke.py for health and migration head, rather than holding a second opinion about whether the service is healthy. RCP-WP-0002 carries the two operator actions that block a first rollout — publishing the image and provisioning database roles — and records per-publisher identity as a decision belonging upstream, which this repo must not paper over with cluster configuration implying finer control than exists. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Bjefh8NUiEiahN4JLwoSKM Assistant: claude-code Assistant-Model: opus Assistant-Process: 388925@bnt-lap001 Assistant-Session: 3507023f-e0fd-4a1e-9d90-a0d4217d1502
2026-09-06 21:44:17 +02:00
priority: high
state_hub_task_id: "0b8d206e-bd28-5950-abf7-d824015c09a4"
```
Order matters, and the ordering is the point rather than a convenience:
Publish the image, pin it by digest, and request the database RCP-WP-0002-T01 done. Published forgejo.coulomb.social/coulomb/canned-prompts:0.1.0 and pinned sha256:e0ded3c7fe25... in declarations/rapp.yaml and both manifests. Pinned by digest rather than tag: a tag can be moved, and live-image-digest-match would then pass against something that is no longer what this repo reviewed. Verified after the push by fetching the manifest back by digest rather than trusting the push output. readiness_state draft -> declared. Not deployed, so not `deployed`. T02 requested rather than performed. rapp-postgres now carries consumers/canned-prompts.yaml against its documented PostgresConsumer shape, and its agent has the request. `make provision-consumers`, which mints the OpenBao credentials, was deliberately not run: credential issuance belongs to that repo's operator, and running it from the consuming side would take a decision that is not this repo's, however available the script is. T03 and T04 move to wait behind it. Also corrected a check of my own: I briefly read the cluster list as lacking platform-pg-2 and suspected the manifests targeted a host that does not exist. That was my own truncated output. platform-pg-2 is present and healthy, and the postgres-client label matches what sbom-nexus actually carries in the cluster rather than only what its repo says. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Bjefh8NUiEiahN4JLwoSKM Assistant: claude-code Assistant-Model: opus Assistant-Process: 388925@bnt-lap001 Assistant-Session: 3507023f-e0fd-4a1e-9d90-a0d4217d1502
2026-09-07 08:43:35 +02:00
Verified against the live cluster before writing: `platform-pg-2` exists and is
healthy, and the `railiance.io/postgres-client: platform-pg-2` label matches
what `sbom-nexus` actually carries in the cluster rather than only what its repo
says.
Package canned-prompts for Railiance Registers the repo with State Hub (agents / practice, prefix RCP-WP) and fills in the rapp shape. declarations/rapp.yaml declares a manifest-managed platform service owned by canned-prompts, bound to rail-kubernetes and reef-railiance, with rollout, smoke and rollback contracts. The image pin says `pending-publication` rather than carrying a placeholder digest. The image builds and was verified locally (canned-prompts CANP-WP-0006-T06) but has never been pushed, so no registry digest exists. A placeholder shaped like a real digest would be worse than a sentinel: it could be mistaken for something deployable. manifests/ follows the rapp-sbom-nexus shape: namespace labelled for the postgres client, external secrets from OpenBao, a migration Job, and the runtime Deployment with a ClusterIP-only Service, dedicated ServiceAccount and default-deny plus runtime NetworkPolicies. Three choices worth stating. Credentials arrive as mounted files, never env vars — an env var holding a password is visible in kubectl describe, in crash dumps, and to anything that can read /proc. Migrations run as a Job rather than at start-up, so a schema rollback stays separate from a code rollback and replicas do not race. Liveness points at /healthz, which checks only that the process is up: pointing it at a database-dependent path would restart every replica during a database blip. Egress is PostgreSQL and DNS only. A package arrives by publish; the registry never reaches out, so it is given no path to. tools/smoke.sh checks what only the cluster can answer and calls canned-prompts' service/tools/smoke.py for health and migration head, rather than holding a second opinion about whether the service is healthy. RCP-WP-0002 carries the two operator actions that block a first rollout — publishing the image and provisioning database roles — and records per-publisher identity as a decision belonging upstream, which this repo must not paper over with cluster configuration implying finer control than exists. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Bjefh8NUiEiahN4JLwoSKM Assistant: claude-code Assistant-Model: opus Assistant-Process: 388925@bnt-lap001 Assistant-Session: 3507023f-e0fd-4a1e-9d90-a0d4217d1502
2026-09-06 21:44:17 +02:00
1. `manifests/00-namespace.yaml` — the `railiance.io/postgres-client` label is
what lets the database namespace accept traffic;
2. `manifests/database-secrets.yaml`, then wait for the secrets to materialize;
3. `manifests/migration.yaml` — the Job runs `alembic upgrade head` under the
migration role and must complete before any replica serves;
4. `manifests/runtime.yaml`.
The runtime deliberately does not migrate at start-up. Migrations as a Job keep
a schema rollback separate from a code rollback and stop replicas racing each
other.
## Verify and record evidence
```task
id: RCP-WP-0002-T04
Publish the image, pin it by digest, and request the database RCP-WP-0002-T01 done. Published forgejo.coulomb.social/coulomb/canned-prompts:0.1.0 and pinned sha256:e0ded3c7fe25... in declarations/rapp.yaml and both manifests. Pinned by digest rather than tag: a tag can be moved, and live-image-digest-match would then pass against something that is no longer what this repo reviewed. Verified after the push by fetching the manifest back by digest rather than trusting the push output. readiness_state draft -> declared. Not deployed, so not `deployed`. T02 requested rather than performed. rapp-postgres now carries consumers/canned-prompts.yaml against its documented PostgresConsumer shape, and its agent has the request. `make provision-consumers`, which mints the OpenBao credentials, was deliberately not run: credential issuance belongs to that repo's operator, and running it from the consuming side would take a decision that is not this repo's, however available the script is. T03 and T04 move to wait behind it. Also corrected a check of my own: I briefly read the cluster list as lacking platform-pg-2 and suspected the manifests targeted a host that does not exist. That was my own truncated output. platform-pg-2 is present and healthy, and the postgres-client label matches what sbom-nexus actually carries in the cluster rather than only what its repo says. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Bjefh8NUiEiahN4JLwoSKM Assistant: claude-code Assistant-Model: opus Assistant-Process: 388925@bnt-lap001 Assistant-Session: 3507023f-e0fd-4a1e-9d90-a0d4217d1502
2026-09-07 08:43:35 +02:00
status: wait
Package canned-prompts for Railiance Registers the repo with State Hub (agents / practice, prefix RCP-WP) and fills in the rapp shape. declarations/rapp.yaml declares a manifest-managed platform service owned by canned-prompts, bound to rail-kubernetes and reef-railiance, with rollout, smoke and rollback contracts. The image pin says `pending-publication` rather than carrying a placeholder digest. The image builds and was verified locally (canned-prompts CANP-WP-0006-T06) but has never been pushed, so no registry digest exists. A placeholder shaped like a real digest would be worse than a sentinel: it could be mistaken for something deployable. manifests/ follows the rapp-sbom-nexus shape: namespace labelled for the postgres client, external secrets from OpenBao, a migration Job, and the runtime Deployment with a ClusterIP-only Service, dedicated ServiceAccount and default-deny plus runtime NetworkPolicies. Three choices worth stating. Credentials arrive as mounted files, never env vars — an env var holding a password is visible in kubectl describe, in crash dumps, and to anything that can read /proc. Migrations run as a Job rather than at start-up, so a schema rollback stays separate from a code rollback and replicas do not race. Liveness points at /healthz, which checks only that the process is up: pointing it at a database-dependent path would restart every replica during a database blip. Egress is PostgreSQL and DNS only. A package arrives by publish; the registry never reaches out, so it is given no path to. tools/smoke.sh checks what only the cluster can answer and calls canned-prompts' service/tools/smoke.py for health and migration head, rather than holding a second opinion about whether the service is healthy. RCP-WP-0002 carries the two operator actions that block a first rollout — publishing the image and provisioning database roles — and records per-publisher identity as a decision belonging upstream, which this repo must not paper over with cluster configuration implying finer control than exists. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Bjefh8NUiEiahN4JLwoSKM Assistant: claude-code Assistant-Model: opus Assistant-Process: 388925@bnt-lap001 Assistant-Session: 3507023f-e0fd-4a1e-9d90-a0d4217d1502
2026-09-06 21:44:17 +02:00
priority: high
state_hub_task_id: "6d9eb97c-57e2-5b74-b6eb-455076713417"
```
Run `tools/smoke.sh`. It checks what only the cluster can answer — secrets
materialized, Service is ClusterIP with no Ingress, NetworkPolicies present,
live image digest matches the pin — and calls `canned-prompts`'
`service/tools/smoke.py` for health and migration head rather than holding a
second opinion about whether the service is healthy.
Record the output as evidence, then move `readiness_state` to `deployed`, and to
`verified` only with that evidence attached.
## Decide per-publisher identity
```task
id: RCP-WP-0002-T05
status: wait
priority: medium
state_hub_task_id: "1252f3a1-12ce-5bc1-b003-3e8999d03459"
```
Blocked on a decision in `canned-prompts`, recorded here because it is the
thing that decides what this deployment is *for*.
Today the service authenticates a single shared bearer token proving "the
operator". That is adequate for a private in-cluster registry and inadequate for
the collaborative prompting platform the operator described: every token holder
is indistinguishable, so § 20.1 namespace ownership can be enforced against
anonymous callers but not attributed among publishers.
This repo must not paper over that with cluster configuration implying finer
control than exists. When identity lands upstream, revisit the publish-token
secret and the NetworkPolicy ingress rule, which currently admits any namespace.