rapp-canned-prompts/declarations/rapp.yaml

65 lines
2.1 KiB
YAML
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
kind: managed-workload-package
repo_family: rapp
rapp_id: rapp-canned-prompts
repo: rapp-canned-prompts
ownership_repo: canned-prompts
contract_version: 1.0.0
First deployment: verified on railiance01 RCP-WP-0002 T02-T04 done, readiness_state verified with evidence attached rather than ahead of it. rapp-postgres provisioned canned_prompts on platform-pg-2 and sent a database-owner receipt with 12 checks proven live. creds/canned-prompts-publish was deliberately not issued, so the service runs read-only and POST /packages returns 503 explaining why — the intended posture, not a gap. Four defects surfaced that only a real rollout could expose, two of them silent: - SET ROLE opened an implicit transaction that Alembic nested inside rather than owning, so every revision logged as applied and was rolled back. Alembic reported success against an empty database. - The egress NetworkPolicy selected app.kubernetes.io/name, which the migration Job does not carry. The Job matched only the default-deny and succeeded exactly once, because it ran before the policies existed; the next migration would have failed on DNS. Now selects part-of, with ingress split into its own policy so the Job is never reachable. - env.py read database_url rather than resolved_database_url, so the migration could never run where the credential is a mounted file. - live-image-digest-match extracted the pin with a line-offset grep, which returned empty once comments were added above `version:`. The check degraded to reporting "not pinned yet" while a digest was pinned — it could not have passed for any pin. Now parsed as YAML. A verification step that cannot fail is worth less than none, because it is trusted. Evidence: docs/evidence/RCP-WP-0002-T04-first-deployment-2026-09-08.md 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-08 08:56:02 +02:00
readiness_state: verified
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
workload_identity:
name: canned-prompts
package_type: manifest-managed-platform-service
data_classification: internal
criticality: medium
primary_rail: rail-kubernetes
supported_rails:
- rail-kubernetes
bound_reefs:
- reef-railiance
runtime_dependencies:
- kubernetes-api
- openbao-database-secrets-engine
composition:
purpose: >-
Package and operate the canned-prompts hosted registry and index on
Railiance. Format semantics, package validation, API compatibility, the
schema and its migrations, and image publication remain owned by
canned-prompts. PostgreSQL topology, database isolation, backups and
credential issuance remain owned by rapp-postgres and the platform
credential broker.
member_repos:
- repo: rapp-canned-prompts
role: managed runtime package
deployables:
- canned-prompts
upstream_components:
- name: canned-prompts
source: forgejo.coulomb.social/coulomb/canned-prompts
First deployment: verified on railiance01 RCP-WP-0002 T02-T04 done, readiness_state verified with evidence attached rather than ahead of it. rapp-postgres provisioned canned_prompts on platform-pg-2 and sent a database-owner receipt with 12 checks proven live. creds/canned-prompts-publish was deliberately not issued, so the service runs read-only and POST /packages returns 503 explaining why — the intended posture, not a gap. Four defects surfaced that only a real rollout could expose, two of them silent: - SET ROLE opened an implicit transaction that Alembic nested inside rather than owning, so every revision logged as applied and was rolled back. Alembic reported success against an empty database. - The egress NetworkPolicy selected app.kubernetes.io/name, which the migration Job does not carry. The Job matched only the default-deny and succeeded exactly once, because it ran before the policies existed; the next migration would have failed on DNS. Now selects part-of, with ingress split into its own policy so the Job is never reachable. - env.py read database_url rather than resolved_database_url, so the migration could never run where the credential is a mounted file. - live-image-digest-match extracted the pin with a line-offset grep, which returned empty once comments were added above `version:`. The check degraded to reporting "not pinned yet" while a digest was pinned — it could not have passed for any pin. Now parsed as YAML. A verification step that cannot fail is worth less than none, because it is trusted. Evidence: docs/evidence/RCP-WP-0002-T04-first-deployment-2026-09-08.md 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-08 08:56:02 +02:00
# Published 2026-09-07 from canned-prompts service/Dockerfile, tag 0.1.4.
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
# 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.
First deployment: verified on railiance01 RCP-WP-0002 T02-T04 done, readiness_state verified with evidence attached rather than ahead of it. rapp-postgres provisioned canned_prompts on platform-pg-2 and sent a database-owner receipt with 12 checks proven live. creds/canned-prompts-publish was deliberately not issued, so the service runs read-only and POST /packages returns 503 explaining why — the intended posture, not a gap. Four defects surfaced that only a real rollout could expose, two of them silent: - SET ROLE opened an implicit transaction that Alembic nested inside rather than owning, so every revision logged as applied and was rolled back. Alembic reported success against an empty database. - The egress NetworkPolicy selected app.kubernetes.io/name, which the migration Job does not carry. The Job matched only the default-deny and succeeded exactly once, because it ran before the policies existed; the next migration would have failed on DNS. Now selects part-of, with ingress split into its own policy so the Job is never reachable. - env.py read database_url rather than resolved_database_url, so the migration could never run where the credential is a mounted file. - live-image-digest-match extracted the pin with a line-offset grep, which returned empty once comments were added above `version:`. The check degraded to reporting "not pinned yet" while a digest was pinned — it could not have passed for any pin. Now parsed as YAML. A verification step that cannot fail is worth less than none, because it is trusted. Evidence: docs/evidence/RCP-WP-0002-T04-first-deployment-2026-09-08.md 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-08 08:56:02 +02:00
version: sha256:2fbac3c0d1609a76d9478e540ae5450c5425e8c04e0565cccc6a4eb0180ebcaf
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
rollout_contract:
default_mode: kubectl-server-side-apply
smoke_contract:
required:
- state-health-ok
- migration-at-head
- external-secrets-ready
- private-service-only
- networkpolicies-present
- live-image-digest-match
rollback_contract:
order:
- previous-immutable-image-digest
- apply-reviewed-git-revision
source_documents:
- repo: canned-prompts
path: CannedPromptFormat.md
- repo: canned-prompts
path: service/README.md
- repo: canned-prompts
path: workplans/CANP-WP-0006-hosted-registry-service.md
- repo: repo-manager
path: docs/RailianceAppDeploymentGuide.md