Canonicalize registry docs and read-only ops

This commit is contained in:
2026-06-05 12:07:27 +02:00
parent 114ae9a26e
commit 32c44cc78e
11 changed files with 449 additions and 32 deletions

View File

@@ -95,6 +95,23 @@ curl -s -X PATCH "http://127.0.0.1:8000/tasks/<task_id>" \
- Record significant decisions via `POST /decisions/`.
- Keep forge responsibilities separate from S4 templates and S5 app releases.
## Verification Commands
This repo currently contains documentation, workplans, and read-only operator
entry points. There is no app build, package install, or unit-test command yet.
Use these checks for ordinary edits:
```bash
git diff --check
make registry-docs
make check-tools
make -C /home/worsch/state-hub fix-consistency REPO=railiance-forge
```
`make gitea-status` is read-only but requires a kubeconfig pointed at a
representative Railiance cluster.
**Close:**
1. Update workplan file task statuses.

56
Makefile Normal file
View File

@@ -0,0 +1,56 @@
SHELL := /usr/bin/env bash
.DEFAULT_GOAL := help
GITEA_RELEASE ?= gitea
GITEA_NAMESPACE ?= default
GITEA_DB_CLUSTER ?= gitea-db
GITEA_DB_NAMESPACE ?= databases
REGISTRY_DOCS ?= docs/gitea-container-registry.md docs/gitea-package-registry.md
##@ Operator checks
check-tools: ## Check local tools used by forge operator targets
@missing=0; \
for tool in kubectl helm sops; do \
if command -v $$tool >/dev/null 2>&1; then \
echo "ok: $$tool"; \
else \
echo "missing: $$tool"; \
missing=1; \
fi; \
done; \
if command -v tea >/dev/null 2>&1; then \
echo "ok: tea"; \
else \
echo "optional: tea not found"; \
fi; \
exit $$missing
registry-docs: ## Print canonical registry docs
@for doc in $(REGISTRY_DOCS); do \
printf '\n## %s\n\n' "$$doc"; \
sed -n '1,220p' "$$doc"; \
done
##@ Current Gitea
gitea-status: ## Read-only status for current Gitea runtime and database
kubectl get pods -n $(GITEA_NAMESPACE) -l app.kubernetes.io/instance=$(GITEA_RELEASE)
kubectl get svc -n $(GITEA_NAMESPACE) $(GITEA_RELEASE) --ignore-not-found
kubectl get ingress -n $(GITEA_NAMESPACE) $(GITEA_RELEASE) --ignore-not-found
@if kubectl cnpg status $(GITEA_DB_CLUSTER) -n $(GITEA_DB_NAMESPACE) >/dev/null 2>&1; then \
kubectl cnpg status $(GITEA_DB_CLUSTER) -n $(GITEA_DB_NAMESPACE); \
else \
echo "kubectl cnpg plugin not available; falling back to cnpg resources"; \
kubectl get cluster $(GITEA_DB_CLUSTER) -n $(GITEA_DB_NAMESPACE); \
kubectl get pods -n $(GITEA_DB_NAMESPACE) -l cnpg.io/cluster=$(GITEA_DB_CLUSTER); \
fi
##@ Help
help: ## Show this help
@awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m<target>\033[0m\n"} \
/^[a-zA-Z0-9_-]+:.*?##/ { printf " \033[36m%-20s\033[0m %s\n", $$1, $$2 } \
/^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) }' $(MAKEFILE_LIST)
.PHONY: check-tools registry-docs gitea-status help

View File

@@ -11,7 +11,18 @@ Start with:
1. `INTENT.md`
2. `SCOPE.md`
3. `AGENTS.md`
4. `workplans/`
4. `docs/`
5. `workplans/`
Current implementation status: founding. No live Gitea files have been migrated
from `railiance-apps` yet.
Current implementation status: early extraction. Canonical registry operation
docs and read-only status targets live here now. Deploy-capable Gitea Helm,
SOPS, and manifest files remain in `railiance-apps` until the explicit
migration review in `RAILIANCE-WP-0006-T03`.
Useful entry points:
```bash
make registry-docs
make check-tools
make gitea-status
```

View File

@@ -29,8 +29,9 @@ The practical contract is:
paths;
4. `railiance-apps` consumes forge artifacts and deploys user-facing workloads.
No live Gitea files have been migrated here yet. This repo is being founded as
the future home for that operational surface.
Canonical registry operation docs and read-only forge checks now live here.
Deploy-capable Gitea Helm/SOPS/manifests remain in `railiance-apps` until the
explicit migration gate for live-affecting files is reviewed.
---
@@ -104,16 +105,20 @@ the future home for that operational surface.
## Current State
- Status: founding.
- Implementation: repository contract and first workplan are being created.
- Stability: emerging.
- Usage: intended as the new home for forge responsibilities currently
visible in `railiance-apps`.
- Status: early extraction.
- Implementation: repository contract, registry docs, initial operating
contracts, and read-only operator targets are present.
- Stability: emerging but non-disruptive; no deploy-capable Gitea state has
moved yet.
- Usage: canonical reference point for forge and registry responsibilities
currently transitioning out of `railiance-apps`.
Known starting point:
- `railiance-apps` currently owns Gitea Helm values, registry overlays, ingress,
Gitea Makefile targets, and registry docs.
and deploy-capable Gitea Makefile targets.
- `railiance-forge` owns registry operation docs, operating contracts, and
read-only status entry points.
- `railiance-enablement` owns the intent for delivery templates and developer
paved paths, but not forge runtime operation.
- `railiance-forge` should absorb forge runtime and artifact infrastructure
@@ -167,7 +172,9 @@ Known starting point:
2. Read `INTENT.md` for stable purpose.
3. Read this file for scope and boundaries.
4. Read active files in `workplans/`.
5. For migration context, read
5. For registry operations, read `docs/gitea-container-registry.md` and
`docs/gitea-package-registry.md`.
6. For migration context, read
`/home/worsch/railiance-apps/workplans/RAILIANCE-WP-0006-railiance-forge-extraction.md`.
---

View File

@@ -2,6 +2,9 @@
Date: 2026-06-05
Status: Phase 1 is underway. The remote repository exists and is pushed, so the
earlier Gitea API blocker no longer applies.
This plan starts the extraction of forge ownership from `railiance-apps` into
`railiance-forge` without changing the live Gitea deployment.
@@ -85,7 +88,7 @@ Review gates:
- `railiance-forge` remote exists and is pushed.
- State Hub workplans are synced in both repos.
- Operator confirms the Gitea token/remote creation issue is fixed.
- Operator confirms deploy-capable Gitea ownership should move now.
- `railiance-apps` has compatibility pointers for old paths.
- The plan distinguishes current Gitea operation from future Forgejo cutover.
@@ -112,19 +115,13 @@ Validation:
- `railiance-apps` no longer claims forge runtime ownership.
- App operators can still find registry instructions through pointers.
## Open Blocker
## Remote Status
The local `tea` login named `coulomb` is configured but currently fails with
`invalid username, password or token`. This blocks creation of the remote
`coulomb/railiance-forge` repository through the Gitea API.
Until refreshed credentials are available:
- keep `railiance-forge` local and State Hub-registered;
- do not add an `origin` remote that points to a missing repository;
- avoid claiming remote publication is complete.
`railiance-forge` now has `origin` configured as
`gitea-remote:coulomb/railiance-forge.git` and the local `main` branch is
aligned with `origin/main`.
## Next Recommended Action
Proceed with Phase 1 documentation canonicalization after the operator confirms
that compatibility pointers in `railiance-apps` are acceptable.
Complete Phase 1 documentation canonicalization and Phase 2 read-only operator
targets, then review the deploy-capable Gitea file move separately.

View File

@@ -0,0 +1,84 @@
# Gitea Container Registry
This is the canonical Railiance operating note for the current Gitea container
registry. Compatibility pointers remain in `railiance-apps` while deploy-capable
Gitea Helm and manifest files still live there.
## Registry Target
Use `gitea.coulomb.social` as the approved registry host. The `/v2` ingress is
live as of 2026-05-15 and returns the OCI registry authentication challenge over
HTTPS.
Registry-specific Gitea settings are currently carried in
`/home/worsch/railiance-apps/helm/gitea-registry-values.yaml`, a non-secret
overlay applied after the SOPS values file by `make gitea-deploy`. It explicitly
enables packages, permits container and PyPI uploads without an app-level size
cap, clears globally disabled repo units, and moves `ROOT_URL` to the HTTPS
host.
Image names should use the Gitea owner and package path:
```bash
gitea.coulomb.social/coulomb/state-hub:<tag>
```
The State Hub handoff from `CUST-WP-0011` should publish the locally verified
`state-hub:local` image under that name.
The successful smoke-test tags were:
```bash
gitea.coulomb.social/coulomb/state-hub:6186a99
gitea.coulomb.social/coulomb/state-hub:latest
```
Digest:
```text
sha256:039d29654ccb3754c6ecdbe497c6364bbd8452edcdcb7fa937dd9debf5b734ff
```
## Operator Smoke Test
Use a Gitea personal access token with package read/write permission:
```bash
docker login gitea.coulomb.social
docker tag state-hub:local gitea.coulomb.social/coulomb/state-hub:<tag>
docker push gitea.coulomb.social/coulomb/state-hub:<tag>
docker pull gitea.coulomb.social/coulomb/state-hub:<tag>
```
The `coulomb` organization packages are public by default, so the verified
cluster pull for `state-hub:6186a99` did not require an `imagePullSecret`.
For private packages, create an image pull secret in each consuming namespace:
```bash
kubectl create secret docker-registry gitea-registry \
--docker-server=gitea.coulomb.social \
--docker-username=<gitea-user> \
--docker-password=<package-token> \
--namespace=<namespace>
```
Reference it from workloads as `imagePullSecrets: [{name: gitea-registry}]`.
## Python Packages
The same Gitea package service is used for Python wheels. See
`docs/gitea-package-registry.md` for the publish/install recipe and the
`issue-core` migration notes from `RAILIANCE-WP-0004 I03`.
## Current Storage Notes
The live Gitea pod mounts `gitea-shared-storage` at `/data`; package blobs land
under `/data/packages`. On 2026-05-19 that package directory was about
798.5 MiB.
The PVC is `default/gitea-shared-storage`, 10 GiB, `local-path`, `RWO`. The live
cluster showed no Kubernetes `CronJob` backup resources across namespaces on
2026-05-19. This is acceptable for the current smoke-test images, but heavy tag
growth should wait for the forge/platform backup and retention follow-up in
`docs/initial-operating-contracts.md`.

View File

@@ -0,0 +1,50 @@
# Gitea Package Registry
This is the canonical Railiance operating note for the current Gitea Python
package registry. Compatibility pointers remain in `railiance-apps` while
deploy-capable Gitea Helm and manifest files still live there.
Gitea package support is enabled by
`/home/worsch/railiance-apps/helm/gitea-registry-values.yaml`. That overlay is
applied after the encrypted base values by `make gitea-deploy` and enables both
container packages and Python packages.
## Python Packages
Publish Python wheels to the organization package endpoint:
```bash
python -m build
TWINE_USERNAME=<gitea-user> \
TWINE_PASSWORD=<package-token> \
python -m twine upload \
--repository-url https://gitea.coulomb.social/api/packages/coulomb/pypi \
dist/*
```
Install from the simple index:
```bash
pip install \
--extra-index-url https://<gitea-user>:<package-token>@gitea.coulomb.social/api/packages/coulomb/pypi/simple/ \
issue-core
```
For CI, store the token as a secret and inject it into the package index URL at
build time. Do not commit tokenized index URLs.
## issue-core Migration
The portable deployment path for `vergabe-teilnahme` is:
1. Release `issue-core` from its source repo as a wheel, for example `0.2.0`.
2. Publish the wheel to the Gitea Python package registry.
3. Keep `vergabe-teilnahme/pyproject.toml` on a versioned dependency such as
`issue-core>=0.2,<0.3`.
4. Regenerate `vergabe-teilnahme/uv.lock` from the Gitea PyPI registry after the
package exists there.
5. Build the image on a clean runner that has no sibling `issue-core` checkout.
Registry endpoint ownership lives in `railiance-forge`; the package release and
application dependency lock belong to the `issue-core` and `vergabe-teilnahme`
source repos.

View File

@@ -0,0 +1,89 @@
# Initial Forge Operating Contracts
Last reviewed: 2026-06-05
These contracts are the first explicit boundary for the Railiance forge layer.
They are intentionally operational enough to guide the next file moves, while
leaving live deploy and secret custody changes behind separate review gates.
## Status
- Contract maturity: draft v1.
- Live impact: none; this document does not authorize a deploy or cutover.
- Current forge runtime: Gitea at `gitea.coulomb.social`.
- Future migration target: Forgejo, under a separate cutover workplan.
## Artifact Lifecycle And Provenance
- Source repositories own build definitions, package metadata, and release
versioning.
- `railiance-forge` owns the registry endpoints, registry operating docs,
retention posture, and artifact evidence model.
- `railiance-apps` consumes already-published artifacts in S5 release values and
runbooks.
- Container images should publish immutable commit-SHA tags for release
evidence. Mutable tags such as `latest` are allowed only as convenience
pointers and must not be the sole production reference.
- Python packages should use versioned releases. Internal consumers should pin
compatible ranges in source repos and regenerate locks after the package is
published.
- Release evidence should capture source repo, commit SHA, artifact name,
version/tag, smoke result, and consuming deployment value change.
## Retention And Cleanup
- Smoke-test image tags can be pruned after a newer validated smoke tag exists
and no rollback or diagnosis still references them.
- Production image tags and Python package versions should be retained for at
least the active rollback window of every consuming deployment.
- Deleting a package or image is an operator action, not an automated default,
until package restore has been drilled.
- The current Gitea package data lives under `/data/packages` on the
`default/gitea-shared-storage` PVC. On 2026-05-19 it was about 798.5 MiB of a
10 GiB `local-path` volume.
- Growth inspection belongs in forge operations; durable backup implementation
belongs with the platform storage/database layer.
## Runner Substrate Ownership
- `railiance-forge` owns Gitea/Forgejo Actions runner deployment, runner labels,
runner placement, runner credentials, and runner health evidence.
- `railiance-enablement` owns reusable workflow templates, paved paths, and
developer-facing automation conventions.
- Application repos own app-specific workflows and build scripts.
- `railiance-apps` owns S5 release checks for app manifests and deployment
values, but not the runner substrate those checks execute on.
- Runner secret access must be explicit by label, repository, and workflow
purpose. Broad package or cluster credentials should not be shared across
unrelated jobs.
## Backup And Restore Handoff
- `railiance-forge` defines what must be restorable: Git repositories, package
blobs, registry metadata, runner configuration, and source-forge application
state.
- `railiance-platform` owns the reusable database, object-storage, backup, and
restore mechanisms used by forge workloads.
- Forge data should not become production-critical without a recorded restore
drill for the relevant storage path.
- S5 app releases may consume forge artifacts, but they should cite forge
evidence rather than owning package blob backup procedures themselves.
## Secret Custody
- This repo may reference secret names, SOPS file paths, OpenBao paths, and
operator procedures.
- This repo must not commit decrypted secret values, package tokens, runner
tokens, tokenized package index URLs, or generated credential material.
- Deploy-capable files that reference encrypted values move only after review of
the SOPS/OpenBao handoff and compatibility pointers.
## Observability And Evidence
- `make gitea-status` is the first read-only operator check in this repo.
- Forge health should cover web, Git SSH, container registry, Python package
registry, database, package storage, and runner status.
- Downstream app release evidence should cite forge artifact evidence rather
than repeating registry implementation details.
- Future monitoring should turn the manual status checks into durable signals
once the Railiance observability layer is ready.

View File

@@ -4,7 +4,7 @@ type: workplan
title: "railiance-forge repository foundation"
domain: railiance
repo: railiance-forge
status: active
status: finished
owner: codex
topic_slug: railiance
planning_priority: high
@@ -115,7 +115,7 @@ file move.
```task
id: FORGE-WP-0001-T05
status: todo
status: done
priority: medium
state_hub_task_id: "a5924b97-ccf7-4da0-acea-4f6017fef278"
```
@@ -129,3 +129,6 @@ Create first draft contracts for:
- basic forge observability.
Done when follow-on implementation work can be split into focused workplans.
Completed in `docs/initial-operating-contracts.md`, with read-only operator
entry points in `Makefile` and follow-on migration tracked in `FORGE-WP-0002`.

View File

@@ -0,0 +1,98 @@
---
id: FORGE-WP-0002
type: workplan
title: "Canonical registry docs and read-only forge operations"
domain: railiance
repo: railiance-forge
status: active
owner: codex
topic_slug: railiance
planning_priority: high
created: "2026-06-05"
updated: "2026-06-05"
state_hub_workstream_id: "00c57adc-b8e6-46d6-a963-d6847646a6b0"
---
# Canonical registry docs and read-only forge operations
## Context
The `railiance-forge` remote now exists and the repository is synced with
State Hub. The first safe extraction step is to move registry operating
knowledge and read-only inspection targets before moving deploy-capable Gitea
configuration from `railiance-apps`.
## T01 - Adopt canonical Gitea registry docs
```task
id: FORGE-WP-0002-T01
status: done
priority: high
state_hub_task_id: "16fa09f4-f8fe-4d73-a9b1-7611bbf13dc9"
```
Move canonical container and Python package registry operation notes into
`railiance-forge/docs/`, leaving compatibility pointers in `railiance-apps`.
Done when operators can find registry endpoints, credential handling, package
publish/install recipes, and current storage notes in this repo.
---
## T02 - Add read-only operator targets
```task
id: FORGE-WP-0002-T02
status: done
priority: high
state_hub_task_id: "977af707-e455-4669-aeb5-62ccf31a8d55"
```
Add a forge-side `Makefile` with:
- `make registry-docs`;
- `make check-tools`;
- `make gitea-status`.
Done when the new repo can inspect current Gitea state without owning
deploy-capable Helm or Kubernetes apply commands.
---
## T03 - Prepare deploy-capable Gitea move review
```task
id: FORGE-WP-0002-T03
status: todo
priority: high
state_hub_task_id: "58a8073d-4665-4cf6-a1f8-e4810c7d392d"
```
Review the next candidate move from `railiance-apps`:
- `helm/gitea-values.sops.yaml`;
- `helm/gitea-registry-values.yaml`;
- `manifests/gitea-ingress.yaml`;
- `releases/gitea/values.yaml`;
- `make gitea-deploy`;
- `make gitea-ingress-deploy`.
Done when the move plan is specific enough to preserve secret boundaries,
operator compatibility, and live Gitea stability.
---
## T04 - Re-home parent workplan references
```task
id: FORGE-WP-0002-T04
status: done
priority: medium
state_hub_task_id: "bc0daafa-0b01-479b-9f46-79c6d8fe1c0e"
```
Update `railiance-apps` docs and workplans so registry operation points to
`railiance-forge`, while app release runbooks stay in S5.
Done when the old app-side registry docs are compatibility pointers instead of
competing canonical sources.

View File

@@ -4,7 +4,7 @@ type: workplan
title: "Bootstrap State Hub integration"
domain: railiance
repo: railiance-forge
status: ready
status: archived
owner: codex
topic_slug: railiance
created: "2026-06-05"
@@ -14,13 +14,18 @@ state_hub_workstream_id: "96ff8f40-fc3d-4f48-94e4-c862f2eb866b"
# Bootstrap State Hub integration
This file defines what `railiance-forge` owns, when to use it, and where its boundaries stop.
This generated bootstrap plan records the initial State Hub onboarding for
`railiance-forge`.
It is archived because the generated files have been reviewed, repo-specific
instructions are present, and `FORGE-WP-0001` now carries the real repository
foundation work.
## Review Generated Integration Files
```task
id: RAILIANCE-WP-0001-T01
status: todo
status: done
priority: high
state_hub_task_id: "695cbdcc-ff69-4b83-9611-1080ae5a46ef"
```
@@ -32,7 +37,7 @@ Replace generated placeholders with repo-specific facts where needed.
```task
id: RAILIANCE-WP-0001-T02
status: todo
status: done
priority: high
state_hub_task_id: "60d01b85-1b82-49d0-9a19-f4147f12348f"
```
@@ -45,7 +50,7 @@ changes confidently.
```task
id: RAILIANCE-WP-0001-T03
status: todo
status: done
priority: medium
state_hub_task_id: "41d82631-86fb-4c2f-813d-305e0e18eab6"
```