Compare commits
10 commits
4825cc93c5
...
dc760eb58e
| Author | SHA1 | Date | |
|---|---|---|---|
| dc760eb58e | |||
| 58c3c48d00 | |||
| d0e15767f6 | |||
| bd2913781e | |||
| 7c663d6da5 | |||
| 1186415864 | |||
| 1d944dc497 | |||
| b34d08c358 | |||
| b6712300c6 | |||
| a9301a009c |
20 changed files with 712 additions and 73 deletions
50
.claude/rules/credential-routing.md
Normal file
50
.claude/rules/credential-routing.md
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
# Credential and access routing
|
||||
|
||||
**Audience:** Codex, Claude Code, Grok, and custodian agents that call **llm-connect**
|
||||
for inference. Run this check **before** requesting secrets, API keys, SSH access,
|
||||
login tokens, or database passwords — in any repo, not only `ops-warden`.
|
||||
|
||||
ops-warden **issues SSH certificates only** (`warden sign`, `cert_command`). Every
|
||||
other credential need belongs to another subsystem. **Do not** message
|
||||
`ops-warden` on State Hub expecting a secret value; the reply is a pointer, not a key.
|
||||
|
||||
### Lookup (do this first)
|
||||
|
||||
```bash
|
||||
warden route find "<describe your need>" --json
|
||||
warden route show <catalog-id> --json
|
||||
```
|
||||
|
||||
Requires the `warden` CLI from `~/ops-warden` (`uv tool install .` or `uv run warden`).
|
||||
|
||||
| Agent runtime | How to orient |
|
||||
| --- | --- |
|
||||
| **Codex / Grok** (shell, HTTP State Hub) | `warden route` commands above; inbox `to_agent=railiance-enablement` is for coordination, not secret vending |
|
||||
| **Claude Code** (MCP when available) | `get_domain_summary("custodian")` for workplans; **still** use `warden route` for credential ownership |
|
||||
| **llm-connect** (inference service) | Never put secret retrieval in prompts; route custody to OpenBao/operator paths surfaced by `warden route` |
|
||||
|
||||
### Quick routing table
|
||||
|
||||
| I need… | Owner | ops-warden executes? |
|
||||
| --- | --- | --- |
|
||||
| SSH cert (`adm`/`agt`/`atm`) | ops-warden | **Yes** — `warden sign` |
|
||||
| API key, DB password, provider token | OpenBao (`railiance-platform`) | No — route only |
|
||||
| Login / OIDC / MFA | key-cape / Keycloak | No — route only |
|
||||
| Authorization decision | flex-auth | No — route only |
|
||||
| activity-core → issue-core emission | activity-core + issue-core | No — `warden route show activity-core-issue-sink` |
|
||||
| SSH tunnel | ops-bridge (+ `cert_command` from warden) | No — route only |
|
||||
|
||||
### Anti-patterns (do not do these)
|
||||
|
||||
- `POST /messages/` to `ops-warden` asking for `ISSUE_CORE_API_KEY`, `OPENROUTER_API_KEY`, etc.
|
||||
- Inventing `warden secret`, `warden login`, `warden bao`, `warden tunnel` — they do not exist
|
||||
- Pasting secrets into Git, State Hub, workplans, logs, or chat
|
||||
|
||||
### Other capabilities (reuse-surface)
|
||||
|
||||
Non-credential capabilities are usually discovered through **reuse-surface** federation
|
||||
(`reuse-surface` registry / `capability.*` indexes). Credential routing is inlined in
|
||||
every repo's agent instructions because it is high-frequency, high-risk, and easy to
|
||||
get wrong.
|
||||
|
||||
**Canon:** `~/ops-warden/wiki/CredentialRouting.md` · catalog `~/ops-warden/registry/routing/catalog.yaml`
|
||||
|
|
@ -1,37 +1,41 @@
|
|||
## First Session Protocol
|
||||
|
||||
Triggered when `get_domain_summary("railiance")` shows **no workstreams**.
|
||||
Triggered when `get_domain_summary("financials")` shows **no workplans**.
|
||||
The project is registered but work has not yet been structured.
|
||||
|
||||
**Step 1 — Read, don't write**
|
||||
- `~/the-custodian/canon/projects/railiance/project_charter_v0.1.md` — purpose, scope
|
||||
- `~/the-custodian/canon/projects/railiance/roadmap_v0.1.md` — planned phases
|
||||
- `~/the-custodian/canon/projects/financials/project_charter_v0.1.md` — purpose, scope
|
||||
- `~/the-custodian/canon/projects/financials/roadmap_v0.1.md` — planned phases
|
||||
- Scan repo root: README, directory structure, existing code or docs
|
||||
|
||||
**Step 2 — Survey in-progress work**
|
||||
Look for TODOs, open branches, half-finished files. Note done vs. started but incomplete.
|
||||
|
||||
**Step 3 — Propose workstreams to Bernd**
|
||||
Propose 1–3 workstreams — each a coherent strand, weeks to months, anchored to a
|
||||
**Step 3 — Propose workplans to Bernd**
|
||||
Propose 1–3 workplans — each a coherent strand, weeks to months, anchored to a
|
||||
roadmap phase. **Wait for approval before creating.**
|
||||
|
||||
**Step 4 — Create workplan file first, then DB record (ADR-001)**
|
||||
**Step 4 — Write the workplan file; fix-consistency registers it (ADR-001)**
|
||||
```
|
||||
workplans/railiance-enablement-WP-NNNN-<slug>.md ← write this first
|
||||
workplans/RAILIANCE-WP-NNNN-<slug>.md ← write this, commit it
|
||||
```
|
||||
Then register in the hub:
|
||||
```
|
||||
create_workstream(topic_id="ca369340-a64e-442e-98f1-a4fa7dc74a38", title="...", owner="...", description="...")
|
||||
create_task(workstream_id="<id>", title="...", priority="high|medium|low")
|
||||
Then register by running the consistency check — do **not** call
|
||||
`create_workplan`/`create_task` (or legacy `create_workstream`) yourself;
|
||||
manual registration duplicates what C-06 creates from the file:
|
||||
```bash
|
||||
statehub fix-consistency --repo railiance-enablement
|
||||
```
|
||||
C-06 creates the hub workplan + tasks and writes `state_hub_workstream_id` /
|
||||
`state_hub_task_id` back into the file (legacy field names, kept for
|
||||
compatibility — they hold workplan/task IDs).
|
||||
|
||||
**Step 5 — Record the setup**
|
||||
```
|
||||
add_progress_event(
|
||||
summary="First session: structured railiance into N workstreams, M tasks",
|
||||
summary="First session: structured financials into N workplans, M tasks",
|
||||
event_type="milestone",
|
||||
topic_id="ca369340-a64e-442e-98f1-a4fa7dc74a38",
|
||||
detail={"workstreams": [...], "tasks_created": M}
|
||||
detail={"workplans": [...], "tasks_created": M}
|
||||
)
|
||||
```
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
**Purpose:** OAS S4 Developer Enablement — CI/CD pipelines, developer portal, platform templates
|
||||
|
||||
**Domain:** railiance
|
||||
**Domain:** financials
|
||||
**Repo slug:** railiance-enablement
|
||||
**Topic ID:** ca369340-a64e-442e-98f1-a4fa7dc74a38
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
## Session Protocol
|
||||
|
||||
State Hub: http://127.0.0.1:8000
|
||||
Dev Hub (State Hub API): http://127.0.0.1:8000
|
||||
MCP server name in `~/.claude.json`: `dev-hub`
|
||||
|
||||
**Step 1 — Orient**
|
||||
|
||||
|
|
@ -10,7 +11,7 @@ cat .custodian-brief.md
|
|||
```
|
||||
Then call the MCP tool for richer cross-domain context when MCP tools are exposed:
|
||||
```
|
||||
get_domain_summary("railiance")
|
||||
get_domain_summary("financials")
|
||||
```
|
||||
If MCP tools are unavailable in the current agent session, use the REST API:
|
||||
```bash
|
||||
|
|
@ -39,11 +40,11 @@ curl -s -X PATCH "http://127.0.0.1:8000/messages/<id>/read" \
|
|||
ls workplans/
|
||||
```
|
||||
For each file with `status: ready`, `active`, or `blocked`, note pending
|
||||
`todo`/`in_progress` tasks.
|
||||
`wait`/`todo`/`progress` tasks.
|
||||
|
||||
**Step 4 — Present brief**
|
||||
|
||||
1. **Active workstreams** for `railiance` — title, task counts, blocking decisions
|
||||
1. **Active workplans** for `financials` — title, task counts, blocking decisions
|
||||
2. **Pending tasks** from `workplans/` + any `[repo:railiance-enablement]` hub tasks
|
||||
3. **Goal guidance** — if `goal_guidance` in summary:
|
||||
- `needs_workplan`: surface as top action — *"Repo goal '{title}' has no workplan yet"*
|
||||
|
|
@ -51,33 +52,42 @@ For each file with `status: ready`, `active`, or `blocked`, note pending
|
|||
4. **Suggested next action** — highest-priority open item
|
||||
5. **SBOM status** — flag if `last_sbom_at` is unset for this repo
|
||||
|
||||
If no workstreams: follow First Session Protocol (`first-session.md`).
|
||||
If no workplans: follow First Session Protocol (`first-session.md`).
|
||||
|
||||
**During work:** `record_decision()` · `add_progress_event()` · `resolve_decision()`
|
||||
|
||||
> State Hub is a *read model*. Bootstrap tools (`create_workstream`, `create_task`)
|
||||
> are First Session Protocol only. Work structure belongs in repo files (ADR-001).
|
||||
> State Hub is a *read model*. **Never register workplans or tasks by hand**
|
||||
> (`create_workplan`, `create_task`, or the legacy `create_workstream`) — write
|
||||
> the workplan file in `workplans/` and run `fix-consistency`; its C-06 check
|
||||
> registers the workplan and its tasks in the hub and writes the IDs back into
|
||||
> the file. Manual registration creates duplicates the moment fix-consistency
|
||||
> runs. Work structure belongs in repo files (ADR-001).
|
||||
>
|
||||
> Terminology: "workstream" is the legacy name for workplan. Some API/frontmatter
|
||||
> field names keep it for compatibility (`state_hub_workstream_id`,
|
||||
> `workstream_id` params) — treat them as workplan IDs.
|
||||
|
||||
**Session close:**
|
||||
With MCP tools:
|
||||
```
|
||||
add_progress_event(summary="...", topic_id="ca369340-a64e-442e-98f1-a4fa7dc74a38", workstream_id="<uuid>")
|
||||
add_progress_event(summary="...", topic_id="ca369340-a64e-442e-98f1-a4fa7dc74a38", workplan_id="<uuid>")
|
||||
```
|
||||
Without MCP tools:
|
||||
```bash
|
||||
curl -s -X POST http://127.0.0.1:8000/progress/ \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"topic_id":"ca369340-a64e-442e-98f1-a4fa7dc74a38","workstream_id":"<uuid>","event_type":"note","summary":"what changed","author":"codex"}'
|
||||
-d '{"topic_id":"ca369340-a64e-442e-98f1-a4fa7dc74a38","workplan_id":"<uuid>","event_type":"note","summary":"what changed","author":"codex"}'
|
||||
```
|
||||
If workplan files were modified, ensure the local copy is up to date first:
|
||||
If workplan files were modified, ensure the local copy is up to date first,
|
||||
then sync from the repo checkout:
|
||||
```bash
|
||||
git -C <repo_path> pull --ff-only
|
||||
cd ~/state-hub && make fix-consistency REPO=railiance-enablement
|
||||
git pull --ff-only
|
||||
statehub fix-consistency
|
||||
```
|
||||
For repos where implementation runs on a remote machine (e.g. CoulombCore),
|
||||
use the combined target which pulls before fixing:
|
||||
use the pull-before-fix mode from any shell with the State Hub CLI:
|
||||
```bash
|
||||
cd ~/state-hub && make fix-consistency-remote REPO=railiance-enablement
|
||||
statehub fix-consistency --repo railiance-enablement --remote
|
||||
```
|
||||
**C-15** (DB task ahead of file) is normal in multi-machine workflows — writeback
|
||||
will sync the file to match DB. **C-16** (repo behind remote) blocks all writes
|
||||
|
|
|
|||
|
|
@ -1,19 +1,13 @@
|
|||
## Stack
|
||||
|
||||
<!-- TODO: Fill in language, frameworks, and key dependencies -->
|
||||
- **Language:**
|
||||
- **Key deps:**
|
||||
- **Language:** documentation and reusable CI/CD / platform templates (no application code yet)
|
||||
- **Key deps:** none at present — S4 layer is largely unpopulated
|
||||
|
||||
## Dev Commands
|
||||
|
||||
```bash
|
||||
# TODO: Fill in the standard commands for this repo
|
||||
|
||||
# Install dependencies
|
||||
|
||||
# Run tests
|
||||
|
||||
# Lint / type check
|
||||
|
||||
# Build / package (if applicable)
|
||||
make help # only target currently defined
|
||||
```
|
||||
|
||||
No build, test, or deploy commands exist yet. When S4 work starts (CI/CD
|
||||
templates, SDKs, buildpacks), fill this file in the same change.
|
||||
|
|
|
|||
|
|
@ -1,28 +1,45 @@
|
|||
## Workplan Convention (ADR-001)
|
||||
|
||||
File location: `workplans/railiance-enablement-WP-NNNN-<slug>.md`
|
||||
ID prefix: `RAILIANCE-WP`
|
||||
File location: `workplans/RAILIANCE-WP-NNNN-<slug>.md`
|
||||
ID prefix: `RAILIANCE-WP-`
|
||||
|
||||
Work items originate as files in this repo **before** being registered in the hub.
|
||||
|
||||
Canonical workplan/workstream frontmatter statuses are:
|
||||
Canonical workplan frontmatter statuses are:
|
||||
`proposed`, `ready`, `active`, `blocked`, `backlog`, `finished`, `archived`.
|
||||
Use `proposed` for a newly drafted plan, `ready` after review against current
|
||||
repo state, and `finished` when implementation is complete. `stalled` and
|
||||
`needs_review` are derived health labels, not stored statuses.
|
||||
|
||||
Closed workplans may be moved to `workplans/archived/` with a completion-date
|
||||
prefix: `YYMMDD-railiance-enablement-WP-NNNN-<slug>.md`. The frontmatter id remains
|
||||
prefix: `YYMMDD-RAILIANCE-WP-NNNN-<slug>.md`. The frontmatter id remains
|
||||
unchanged; the prefix is only for quick visual reference.
|
||||
|
||||
Small opportunistic tasks discovered during another session use **Ad Hoc Tasks**:
|
||||
`workplans/ADHOC-YYYY-MM-DD.md`, workstream slug `adhoc-YYYY-MM-DD`, and task ids
|
||||
`workplans/ADHOC-YYYY-MM-DD.md`, workplan slug `adhoc-YYYY-MM-DD`, and task ids
|
||||
`ADHOC-YYYY-MM-DD-T01`, `T02`, etc. Use adhocs only for low-risk work completed
|
||||
directly. Promote anything requiring analysis, design, approval, dependencies, or
|
||||
multiple planned phases into a normal workplan.
|
||||
|
||||
Ecosystem todos from other agents arrive as `[repo:railiance-enablement]` hub tasks —
|
||||
visible at session start. Pick one up by creating the workplan file, then registering
|
||||
the workstream.
|
||||
visible at session start. Pick one up by creating the workplan file, committing,
|
||||
and running `statehub fix-consistency` — C-06 registers the workplan in the hub.
|
||||
Never register by hand with `create_workplan`/`create_workstream`.
|
||||
|
||||
Task blocks use this shape:
|
||||
|
||||
```task
|
||||
id: RAILIANCE-WP-NNNN-T01
|
||||
status: wait | todo | progress | done | cancel
|
||||
priority: high | medium | low
|
||||
state_hub_task_id: "<uuid>" # written by fix-consistency — do not edit
|
||||
```
|
||||
|
||||
Status progression is `todo` → `progress` → `done`; use `wait` for waiting or
|
||||
blocked work and `cancel` for stopped work.
|
||||
|
||||
Workplan frontmatter carries `state_hub_workstream_id` — a legacy field name
|
||||
kept for compatibility ("workstream" is the old term for workplan); it holds
|
||||
the hub workplan id and is written by fix-consistency. Do not edit or rename it.
|
||||
|
||||
<!-- Ralph Loop rules and HEUREKA sequence: ~/.claude/CLAUDE.md — do not duplicate here -->
|
||||
|
|
|
|||
29
.forgejo/workflows/ci-smoke.yaml
Normal file
29
.forgejo/workflows/ci-smoke.yaml
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
# Canonical CI smoke template (tier 1 routing drill).
|
||||
# Copy to: .forgejo/workflows/ci-smoke.yaml in consumer repos.
|
||||
name: CI Smoke
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
host-smoke:
|
||||
runs-on: self-hosted
|
||||
steps:
|
||||
- name: Routing probe (host runner)
|
||||
run: |
|
||||
set -eu
|
||||
echo "repository=${GITHUB_REPOSITORY:-unknown}"
|
||||
echo "sha=${GITHUB_SHA:-unknown}"
|
||||
echo "runner=${RUNNER_NAME:-unknown}"
|
||||
uname -a
|
||||
|
||||
container-smoke:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Routing probe (container label)
|
||||
run: |
|
||||
set -eu
|
||||
echo "container-smoke ok for ${GITHUB_REPOSITORY:-unknown}"
|
||||
17
.repo-classification.yaml
Normal file
17
.repo-classification.yaml
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
repo_classification:
|
||||
standard: Repo Classification Standard
|
||||
version: '1.0'
|
||||
classified_at: '2026-06-22'
|
||||
classified_by: agent
|
||||
category: project
|
||||
domain: financials
|
||||
secondary_domains: []
|
||||
capability_tags:
|
||||
- platform
|
||||
- operations
|
||||
business_stake:
|
||||
- technology
|
||||
- operations
|
||||
business_mechanics:
|
||||
- coordination
|
||||
- operation
|
||||
95
AGENTS.md
95
AGENTS.md
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
**Purpose:** OAS S4 Developer Enablement — CI/CD pipelines, developer portal, platform templates
|
||||
|
||||
**Domain:** railiance
|
||||
**Domain:** financials
|
||||
**Repo slug:** railiance-enablement
|
||||
**Topic ID:** `ca369340-a64e-442e-98f1-a4fa7dc74a38`
|
||||
**Workplan prefix:** `RAILIANCE-WP-`
|
||||
|
|
@ -20,6 +20,12 @@ there is no MCP server for Codex agents.
|
|||
|---------|-----|
|
||||
| Local workstation | `http://127.0.0.1:8000` |
|
||||
| Remote via tunnel | `http://127.0.0.1:18000` |
|
||||
| Optional local edge relay | http://127.0.0.1:18080 |
|
||||
|
||||
When an operator has enabled the edge relay, set API_BASE to the relay URL.
|
||||
Queueable writes return an explicit queued receipt if the central hub is
|
||||
unreachable. Treat that as pending local evidence, then ask the operator to run
|
||||
statehub outbox status/replay after connectivity returns.
|
||||
|
||||
### Orient at session start
|
||||
|
||||
|
|
@ -27,8 +33,8 @@ there is no MCP server for Codex agents.
|
|||
# Offline brief — works without hub connection
|
||||
cat .custodian-brief.md
|
||||
|
||||
# Active workstreams for this domain
|
||||
curl -s "http://127.0.0.1:8000/workstreams/?topic_id=ca369340-a64e-442e-98f1-a4fa7dc74a38&status=active" \
|
||||
# Active workplans for this domain
|
||||
curl -s "http://127.0.0.1:8000/workplans/?topic_id=ca369340-a64e-442e-98f1-a4fa7dc74a38&status=active" \
|
||||
| python3 -m json.tool
|
||||
|
||||
# Check inbox
|
||||
|
|
@ -51,20 +57,20 @@ curl -s -X POST http://127.0.0.1:8000/progress/ \
|
|||
"summary": "what was done",
|
||||
"event_type": "note",
|
||||
"author": "codex",
|
||||
"workstream_id": "<uuid>",
|
||||
"workplan_id": "<uuid>",
|
||||
"task_id": "<uuid>"
|
||||
}'
|
||||
```
|
||||
|
||||
Omit `workstream_id` / `task_id` when not applicable.
|
||||
Omit `workplan_id` / `task_id` when not applicable.
|
||||
|
||||
### Update task status
|
||||
|
||||
```bash
|
||||
curl -s -X PATCH "http://127.0.0.1:8000/tasks/<task_id>" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"status": "in_progress"}'
|
||||
# values: todo | in_progress | done | blocked
|
||||
-d '{"status": "progress"}'
|
||||
# values: wait | todo | progress | done | cancel
|
||||
```
|
||||
|
||||
### Flag a task for human review
|
||||
|
|
@ -80,10 +86,10 @@ curl -s -X PATCH "http://127.0.0.1:8000/tasks/<task_id>" \
|
|||
## Session Protocol
|
||||
|
||||
**Start:**
|
||||
1. `cat .custodian-brief.md` — domain goal and open workstreams (offline-safe)
|
||||
1. `cat .custodian-brief.md` — domain goal and open workplans (offline-safe)
|
||||
2. Check inbox: `GET /messages/?to_agent=railiance-enablement&unread_only=true`; mark read
|
||||
3. Scan workplans: `ls workplans/` — note `status: ready`, `active`, or `blocked` files and open tasks
|
||||
4. Check blocked tasks: `GET /tasks/?needs_human=true`
|
||||
4. Check human-needed tasks: `GET /tasks/?needs_human=true`
|
||||
|
||||
**During work:**
|
||||
- Update task statuses in workplan files as tasks progress
|
||||
|
|
@ -92,12 +98,69 @@ curl -s -X PATCH "http://127.0.0.1:8000/tasks/<task_id>" \
|
|||
**Close:**
|
||||
1. Update workplan file task statuses to reflect progress
|
||||
2. Log: `POST /progress/` with a summary of what changed
|
||||
3. Note for the custodian operator: after workplan file changes, run from
|
||||
`~/state-hub`:
|
||||
3. After workplan file changes, run:
|
||||
```bash
|
||||
make fix-consistency REPO=railiance-enablement
|
||||
statehub fix-consistency
|
||||
```
|
||||
This syncs task status from files into the hub DB.
|
||||
Coding agents should run this directly; ask the operator only if the CLI or
|
||||
State Hub API is unavailable. This syncs task status from files into the hub DB.
|
||||
|
||||
---
|
||||
|
||||
## Credential and access routing
|
||||
|
||||
**Audience:** Codex, Claude Code, Grok, and custodian agents that call **llm-connect**
|
||||
for inference. Run this check **before** requesting secrets, API keys, SSH access,
|
||||
login tokens, or database passwords — in any repo, not only `ops-warden`.
|
||||
|
||||
ops-warden **issues SSH certificates only** (`warden sign`, `cert_command`). Every
|
||||
other credential need belongs to another subsystem. **Do not** message
|
||||
`ops-warden` on State Hub expecting a secret value; the reply is a pointer, not a key.
|
||||
|
||||
### Lookup (do this first)
|
||||
|
||||
```bash
|
||||
warden route find "<describe your need>" --json
|
||||
warden route show <catalog-id> --json
|
||||
```
|
||||
|
||||
Requires the `warden` CLI from `~/ops-warden` (`uv tool install .` or `uv run warden`).
|
||||
|
||||
| Agent runtime | How to orient |
|
||||
| --- | --- |
|
||||
| **Codex / Grok** (shell, HTTP State Hub) | `warden route` commands above; inbox `to_agent=railiance-enablement` is for coordination, not secret vending |
|
||||
| **Claude Code** (MCP when available) | `get_domain_summary("custodian")` for workplans; **still** use `warden route` for credential ownership |
|
||||
| **llm-connect** (inference service) | Never put secret retrieval in prompts; route custody to OpenBao/operator paths surfaced by `warden route` |
|
||||
|
||||
### Quick routing table
|
||||
|
||||
| I need… | Owner | ops-warden executes? |
|
||||
| --- | --- | --- |
|
||||
| SSH cert (`adm`/`agt`/`atm`) | ops-warden | **Yes** — `warden sign` |
|
||||
| API key, DB password, provider token | OpenBao (`railiance-platform`) | No — route only |
|
||||
| Login / OIDC / MFA | key-cape / Keycloak | No — route only |
|
||||
| Authorization decision | flex-auth | No — route only |
|
||||
| activity-core → issue-core emission | activity-core + issue-core | No — `warden route show activity-core-issue-sink` |
|
||||
| SSH tunnel | ops-bridge (+ `cert_command` from warden) | No — route only |
|
||||
|
||||
### Anti-patterns (do not do these)
|
||||
|
||||
- `POST /messages/` to `ops-warden` asking for `ISSUE_CORE_API_KEY`, `OPENROUTER_API_KEY`, etc.
|
||||
- Inventing `warden secret`, `warden login`, `warden bao`, `warden tunnel` — they do not exist
|
||||
- Pasting secrets into Git, State Hub, workplans, logs, or chat
|
||||
|
||||
### Other capabilities (reuse-surface)
|
||||
|
||||
Non-credential capabilities are usually discovered through **reuse-surface** federation
|
||||
(`reuse-surface` registry / `capability.*` indexes). Credential routing is inlined in
|
||||
every repo's agent instructions because it is high-frequency, high-risk, and easy to
|
||||
get wrong.
|
||||
|
||||
**Canon:** `~/ops-warden/wiki/CredentialRouting.md` · catalog `~/ops-warden/registry/routing/catalog.yaml`
|
||||
|
||||
<!-- REPO-AGENTS-EXTENSIONS -->
|
||||
<!-- Append repo-specific agent instructions below this marker.
|
||||
The state-hub template sync preserves content after this line. -->
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -124,7 +187,7 @@ anything needing analysis, design, approval, dependencies, or multiple phases.
|
|||
id: RAILIANCE-WP-NNNN
|
||||
type: workplan
|
||||
title: "..."
|
||||
domain: railiance
|
||||
domain: financials
|
||||
repo: railiance-enablement
|
||||
status: proposed | ready | active | blocked | backlog | finished | archived
|
||||
owner: codex
|
||||
|
|
@ -146,7 +209,7 @@ derived health labels, not frontmatter statuses.
|
|||
|
||||
` ` `task
|
||||
id: RAILIANCE-WP-NNNN-T01
|
||||
status: todo | in_progress | done | blocked
|
||||
status: wait | todo | progress | done | cancel
|
||||
priority: high | medium | low
|
||||
state_hub_task_id: "<uuid>" # written by fix-consistency — do not edit
|
||||
` ` `
|
||||
|
|
@ -154,7 +217,7 @@ state_hub_task_id: "<uuid>" # written by fix-consistency — do not edit
|
|||
Task description text.
|
||||
```
|
||||
|
||||
Status progression: `todo` → `in_progress` → `done` (or `blocked`)
|
||||
Status progression: `todo` → `progress` → `done`; use `wait` for waiting/blocked work and `cancel` for stopped work.
|
||||
|
||||
To create a new workplan:
|
||||
1. Write the file following the format above
|
||||
|
|
|
|||
|
|
@ -8,4 +8,5 @@
|
|||
@.claude/rules/stack-and-commands.md
|
||||
@.claude/rules/architecture.md
|
||||
@.claude/rules/repo-boundary.md
|
||||
@.claude/rules/credential-routing.md
|
||||
@.claude/rules/agents.md
|
||||
|
|
|
|||
150
INTENT.md
Normal file
150
INTENT.md
Normal file
|
|
@ -0,0 +1,150 @@
|
|||
# INTENT
|
||||
|
||||
> This file captures **why this repository exists**,
|
||||
> the **direction it is moving toward**, and
|
||||
> the **kind of system it is meant to become**.
|
||||
> It is intentionally **aspirational and stable**, not a description of current implementation.
|
||||
|
||||
---
|
||||
|
||||
## One-liner
|
||||
|
||||
**The developer enablement layer - turning Railiance platform capabilities into paved paths for building, testing, packaging, and promoting workloads.**
|
||||
|
||||
---
|
||||
|
||||
## Why This Exists
|
||||
|
||||
A healthy platform does not automatically make delivery easy.
|
||||
Developers and operators still need repeatable ways to build workloads, test
|
||||
them, package them, route them through review, and hand them to application
|
||||
release surfaces without inventing those paths from scratch each time.
|
||||
|
||||
Without a disciplined enablement layer:
|
||||
|
||||
* every workload invents a different pipeline,
|
||||
* build and deployment templates drift,
|
||||
* platform capabilities are hard to consume correctly,
|
||||
* and application releases depend on undocumented operator memory.
|
||||
|
||||
This layer exists to provide **paved delivery paths**: shared automation,
|
||||
templates, SDKs, build conventions, and self-service workflows that let
|
||||
Railiance evolve faster without dissolving its layer boundaries.
|
||||
|
||||
---
|
||||
|
||||
## The Mission
|
||||
|
||||
> *Where we are going.*
|
||||
|
||||
To become the **canonical home for developer and delivery enablement** -
|
||||
CI/CD pipelines, GitOps workflows, workload templates, SDKs, buildpacks,
|
||||
developer portal surfaces, and promotion conventions that help source repos
|
||||
move safely toward S5 application releases while consuming forge-provided
|
||||
runners, registries, and artifact evidence.
|
||||
|
||||
This means:
|
||||
|
||||
* Common delivery paths are **automated and reusable**
|
||||
* Build and deployment templates encode **Railiance platform expectations**
|
||||
* Developers get fast feedback through **standard checks and pipelines**
|
||||
* S5 can consume release artifacts through **clear handoff contracts**
|
||||
* Forge runtime and runner substrate remain owned by **railiance-forge**
|
||||
* Enablement improves delivery without taking ownership of app runtime
|
||||
operation
|
||||
|
||||
---
|
||||
|
||||
## Core Principles
|
||||
|
||||
### 1. Paved Paths, Not One-Off Pipelines
|
||||
|
||||
The default way to build, test, package, and promote a workload should be
|
||||
shared, documented, and easy to reuse.
|
||||
|
||||
### 2. Enablement, Not Applications
|
||||
|
||||
This layer helps applications reach production; it does not own their source
|
||||
code, runtime configuration, or user-facing operations.
|
||||
|
||||
### 3. Platform-Aware Templates
|
||||
|
||||
Templates, SDKs, and buildpacks should encode the contracts exposed by S1-S3 so
|
||||
consumers do not need to rediscover platform assumptions.
|
||||
|
||||
### 4. Clear Handoff to S5
|
||||
|
||||
CI/CD and promotion flows should produce artifacts, metadata, and evidence that
|
||||
the application layer can deploy and verify without guessing.
|
||||
|
||||
### 5. Clear Handoff to Forge
|
||||
|
||||
Reusable workflows should state the forge capabilities they require: repository
|
||||
events, runner labels, package credentials, registry endpoints, and artifact
|
||||
evidence. This layer defines the reusable workflow shape; `railiance-forge`
|
||||
owns the runtime and credentials behind it.
|
||||
|
||||
### 6. Fast Feedback
|
||||
|
||||
Developers should learn about broken builds, missing declarations, incompatible
|
||||
interfaces, and release-readiness gaps before those problems reach live
|
||||
application deployments.
|
||||
|
||||
### 7. Boundaries Preserve Velocity
|
||||
|
||||
Enablement should make the layered architecture easier to use, not become a
|
||||
shortcut for mutating infrastructure, cluster, platform, or application
|
||||
responsibilities.
|
||||
|
||||
---
|
||||
|
||||
## What This Is (Conceptually)
|
||||
|
||||
This layer is:
|
||||
|
||||
* a **developer enablement** layer
|
||||
* a home for **CI/CD and GitOps workflow patterns**
|
||||
* a source of **workload templates, SDKs, and buildpacks**
|
||||
* a **promotion handoff** surface between source repos and S5 deployments
|
||||
* a future **developer portal** and self-service entry point
|
||||
* a place to codify delivery knowledge into **repeatable automation**
|
||||
|
||||
---
|
||||
|
||||
## What This Is Not
|
||||
|
||||
This layer is not:
|
||||
|
||||
* the infrastructure substrate
|
||||
* the Kubernetes runtime
|
||||
* the shared platform-services layer
|
||||
* the application deployment and operations layer
|
||||
* the source forge, package/container registry, or runner substrate layer
|
||||
* the source-code home for business workloads
|
||||
* a replacement for repo-owned workplans, ADRs, or implementation decisions
|
||||
|
||||
It is the **delivery machinery** that helps the rest of Railiance change
|
||||
safely and repeatedly.
|
||||
|
||||
---
|
||||
|
||||
## Direction of Evolution
|
||||
|
||||
This layer is expected to evolve toward:
|
||||
|
||||
* Standard **pipeline templates** for Railiance workloads
|
||||
* Reusable **build and image promotion** conventions
|
||||
* GitOps workflows with clear **review and rollback** expectations
|
||||
* Handoff contracts with `railiance-forge` for **runner labels, package
|
||||
credentials, registry endpoints, and artifact evidence**
|
||||
* Reusable templates that cite the forge-owned **runner/GitOps ownership
|
||||
contract** before depending on privileged labels or credentials
|
||||
* Developer-facing **self-service templates** and portal entry points
|
||||
* SDKs and examples that make platform capabilities easy to consume correctly
|
||||
* Release evidence that S5 can use for **deployment readiness**
|
||||
|
||||
---
|
||||
|
||||
## Guiding Question
|
||||
|
||||
> **How can Railiance make the correct delivery path the easiest path, so workloads can move from source to production with speed, evidence, and clear ownership?**
|
||||
53
SCOPE.md
53
SCOPE.md
|
|
@ -8,23 +8,33 @@
|
|||
|
||||
## One-liner
|
||||
|
||||
S4 Developer Enablement layer of the Railiance OAS Stack — owns CI/CD pipelines, developer portal, platform templates, SDKs, and buildpacks.
|
||||
S4 Developer Enablement layer of the Railiance OAS Stack — owns reusable CI/CD
|
||||
templates, developer portal paths, platform templates, SDKs, and buildpacks;
|
||||
uses forge capabilities without owning forge runtime or runner substrate.
|
||||
|
||||
---
|
||||
|
||||
## Core Idea
|
||||
|
||||
Railiance is structured as five independent repos per OAS Stack layer. This repo is S4 — the tools that allow the system to evolve. S4 depends on the platform (S3) being operational before any tooling can use platform services, and in turn S5 (applications) uses S4's CI/CD pipelines and deployment templates.
|
||||
Railiance is structured as independent repos per OAS Stack layer. This repo is
|
||||
S4: the reusable tools and paved paths that allow the system to evolve. S4
|
||||
depends on the platform (S3) being operational before tooling can use platform
|
||||
services. S5 applications consume S4 templates and conventions, while
|
||||
`railiance-forge` provides source hosting, registries, and runner substrate.
|
||||
|
||||
---
|
||||
|
||||
## In Scope
|
||||
|
||||
- CI/CD pipelines and automation tooling
|
||||
- Reusable CI/CD workflow templates and automation patterns
|
||||
- Developer portal (self-service deployment interface)
|
||||
- Platform deployment templates for workloads
|
||||
- SDKs and libraries for platform consumers
|
||||
- Buildpacks and image builders
|
||||
- Handoff contracts to `railiance-forge` for runner labels, artifact evidence,
|
||||
and registry consumption
|
||||
- Template references to forge-provided runner labels and credentials documented
|
||||
in `/home/worsch/railiance-forge/docs/ci-runner-actions-gitops-ownership.md`
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -33,7 +43,10 @@ Railiance is structured as five independent repos per OAS Stack layer. This repo
|
|||
- OS-level concerns → railiance-infra (S1)
|
||||
- Kubernetes runtime → railiance-cluster (S2)
|
||||
- Platform services → railiance-platform (S3)
|
||||
- Source forge runtime, container/package registries, runner deployment,
|
||||
runner labels, and runner credentials → railiance-forge
|
||||
- Application deployments → railiance-apps (S5)
|
||||
- App-specific workflows, release charts, and source code → app/source repos
|
||||
- No re-configuration of lower layers from this repo
|
||||
|
||||
---
|
||||
|
|
@ -42,6 +55,8 @@ Railiance is structured as five independent repos per OAS Stack layer. This repo
|
|||
|
||||
- Setting up CI/CD for the Railiance stack
|
||||
- Creating or modifying developer tools and deployment templates
|
||||
- Defining reusable workflow templates that run on forge-provided runners
|
||||
- Defining promotion conventions and evidence formats consumed by S5
|
||||
- S3 is operational and tooling layer can now be built
|
||||
|
||||
---
|
||||
|
|
@ -50,35 +65,53 @@ Railiance is structured as five independent repos per OAS Stack layer. This repo
|
|||
|
||||
- S3 (platform services) is not yet operational (pre-condition not met)
|
||||
- Infrastructure, cluster, or platform work needed (wrong layer)
|
||||
- The work is Gitea/Forgejo runtime, registry endpoint, package retention,
|
||||
runner deployment, or runner secret access (use `railiance-forge`)
|
||||
- The work is a concrete app release or app-specific runbook (use
|
||||
`railiance-apps` or the source app repo)
|
||||
|
||||
---
|
||||
|
||||
## Current State
|
||||
|
||||
- Status: emerging (ArgoCD deployed; no S4 workplans yet)
|
||||
- Implementation: ArgoCD is deployed in the `argocd` namespace on COULOMBCORE — installed as a cluster addon (managed from S2 for now); no S4-owned workplans yet
|
||||
- Implementation: ArgoCD is deployed in the `argocd` namespace on COULOMBCORE
|
||||
as a cluster addon managed from S2 for now; no S4-owned workplans yet
|
||||
- Stability: n/a for S4-owned content; ArgoCD itself is operational
|
||||
- Usage: ArgoCD available for GitOps deployments; formal S4 tooling work begins after S3 baseline
|
||||
- Usage: ArgoCD available for GitOps deployments; formal S4 tooling work begins
|
||||
after S3 baseline and should consume runner/registry capabilities from
|
||||
`railiance-forge`
|
||||
|
||||
---
|
||||
|
||||
## How It Fits
|
||||
|
||||
- Upstream dependencies: railiance-platform (S3) must be operational
|
||||
- Downstream consumers: railiance-apps (S5) uses CI/CD and templates from this layer
|
||||
- Often used with: railiance-platform (S3), railiance-apps (S5)
|
||||
- Adjacent forge provider: railiance-forge owns source hosting, registries, and
|
||||
runner substrate used by S4 workflows
|
||||
- Downstream consumers: railiance-apps (S5) uses CI/CD and templates from this
|
||||
layer
|
||||
- Often used with: railiance-platform (S3), railiance-forge, railiance-apps (S5)
|
||||
|
||||
---
|
||||
|
||||
## Terminology
|
||||
|
||||
- Preferred terms: OAS Stack Level S4, developer enablement, boundary rule
|
||||
- Preferred terms: OAS Stack Level S4, developer enablement, paved path,
|
||||
workflow template, promotion convention, boundary rule
|
||||
- Distinguish "workflow template" from "runner substrate": templates live here;
|
||||
runner deployment, labels, credentials, and health live in
|
||||
`railiance-forge`.
|
||||
|
||||
---
|
||||
|
||||
## Related / Overlapping
|
||||
|
||||
- `railiance-platform` (S3) — pre-condition; provides services that S4 tooling depends on
|
||||
- `railiance-forge` — provides source forge runtime, artifact registries, and
|
||||
runner substrate consumed by S4 workflows; its runner label and GitOps
|
||||
boundary contract is
|
||||
`/home/worsch/railiance-forge/docs/ci-runner-actions-gitops-ownership.md`
|
||||
- `railiance-apps` (S5) — consumer of S4 CI/CD and templates
|
||||
|
||||
---
|
||||
|
|
@ -89,13 +122,13 @@ Railiance is structured as five independent repos per OAS Stack layer. This repo
|
|||
type: infrastructure
|
||||
title: CI/CD pipeline automation
|
||||
description: Automated build, test, and deployment pipelines for Railiance workloads — planned for when railiance-platform (S3) is operational.
|
||||
keywords: [ci, cd, pipeline, automation, build, deploy, gitops]
|
||||
keywords: [ci, cd, pipeline, automation, template, build, deploy, gitops]
|
||||
```
|
||||
|
||||
```capability
|
||||
type: documentation
|
||||
title: Platform deployment templates and SDKs
|
||||
description: Standardised deployment templates, Helm charts, and SDKs enabling consistent application deployments across the Railiance stack.
|
||||
description: Standardised deployment templates, Helm chart patterns, SDKs, and promotion conventions enabling consistent application deployments across the Railiance stack while consuming forge-owned runners and registries.
|
||||
keywords: [template, sdk, helm, deployment, developer, buildpack]
|
||||
```
|
||||
|
||||
|
|
|
|||
66
docs/forgejo-actions-workflow-templates.md
Normal file
66
docs/forgejo-actions-workflow-templates.md
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
# Forgejo Actions Workflow Templates
|
||||
|
||||
Date: 2026-07-04
|
||||
Owner: `railiance-enablement` (S4)
|
||||
Workplans: `RAIL-HO-WP-0005-T08`, `CUST-WP-0054-T04`
|
||||
|
||||
## Purpose
|
||||
|
||||
Canonical, copy-ready Forgejo Actions workflows for the railiance01 runner
|
||||
substrate (`railiance01-build-01`, ADR-004). Forgejo/Gitea Actions on our
|
||||
runners do **not** support `actions/checkout@v4` on the non-root host runner;
|
||||
use **archive checkout** via `wget` instead.
|
||||
|
||||
Templates live in `workflows/` at repo root. Consumer repos copy into
|
||||
`.forgejo/workflows/` and adjust `IMAGE_NAME` / `EXTRA_REPOS` as needed.
|
||||
|
||||
## Runner labels
|
||||
|
||||
| Label | Use |
|
||||
| --- | --- |
|
||||
| `self-hosted` | Host runner routing smoke, lightweight probes |
|
||||
| `ubuntu-latest` | Container-isolated smoke (label routing) |
|
||||
| `container-build` | DinD image build + registry push |
|
||||
|
||||
Org secrets (set on `coulomb` org): `REGISTRY_USER`, `REGISTRY_TOKEN`.
|
||||
|
||||
## Templates
|
||||
|
||||
| File | Tier | When to use |
|
||||
| --- | ---: | --- |
|
||||
| `workflows/ci-smoke.yaml` | 1 | Git+CI routing drill; infra/docs repos |
|
||||
| `workflows/container-build-push.yaml` | 2 | Single-repo `Dockerfile` image publish |
|
||||
| `workflows/container-build-push-multirepo.yaml` | 3 prep | Docker build with named contexts (e.g. `state-hub` + `hub-core`) |
|
||||
|
||||
## Adoption
|
||||
|
||||
```bash
|
||||
mkdir -p .forgejo/workflows
|
||||
cp /path/to/railiance-enablement/workflows/ci-smoke.yaml .forgejo/workflows/
|
||||
# For images:
|
||||
cp /path/to/railiance-enablement/workflows/container-build-push.yaml .forgejo/workflows/image.yaml
|
||||
# Edit IMAGE_NAME=coulomb/<repo>
|
||||
git add .forgejo/workflows && git commit -m "Add Forgejo CI from enablement templates"
|
||||
git push origin main
|
||||
```
|
||||
|
||||
## Proven consumers
|
||||
|
||||
| Repo | Template | Evidence |
|
||||
| --- | --- | --- |
|
||||
| `coulomb/glas-harness` | `ci-smoke` (in-repo) | Tier 1 pilot |
|
||||
| `coulomb/key-cape` | `container-build-push` (in-repo) | Tier 2 pilot |
|
||||
| `coulomb/railiance-*` | `ci-smoke` | Tier 2.5 promotion (2026-07-04) |
|
||||
|
||||
## Constraints
|
||||
|
||||
- Do not use `actions/checkout@v4` on `self-hosted` / `container-build` runners.
|
||||
- Static `docker` binary via wget; runner image is non-root and cannot `apk add`.
|
||||
- Reusable `workflow_call` across repos is not relied on; copy templates instead.
|
||||
- Runner substrate and labels: `railiance-forge/docs/ci-runner-actions-gitops-ownership.md`.
|
||||
|
||||
## References
|
||||
|
||||
- `the-custodian/docs/forgejo-repo-migration-pilot-glas-harness.md`
|
||||
- `railiance-apps/docs/forgejo-on-railiance01.md`
|
||||
- `docs/adr/ADR-004-forgejo-in-cluster-actions-runner.md` (in `railiance-infra`)
|
||||
12
registry/README.md
Normal file
12
registry/README.md
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
# Capability Registry
|
||||
|
||||
Markdown-first capability index for federation and reuse planning.
|
||||
|
||||
## Authoring
|
||||
|
||||
1. Copy a capability entry template (see reuse-surface `templates/capability-entry.template.md`).
|
||||
2. Add the row to `indexes/capabilities.yaml`.
|
||||
3. Run `reuse-surface validate` from a checkout with the CLI installed.
|
||||
4. Merge to `main` and verify publish with `reuse-surface establish --publish-check`.
|
||||
|
||||
Federation contract: reuse-surface `docs/RegistryFederation.md`.
|
||||
0
registry/capabilities/.gitkeep
Normal file
0
registry/capabilities/.gitkeep
Normal file
4
registry/indexes/capabilities.yaml
Normal file
4
registry/indexes/capabilities.yaml
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
version: 1
|
||||
updated: '2026-06-16'
|
||||
domain: helix_forge
|
||||
capabilities: []
|
||||
51
tools/promote-repo-to-forgejo.sh
Executable file
51
tools/promote-repo-to-forgejo.sh
Executable file
|
|
@ -0,0 +1,51 @@
|
|||
#!/usr/bin/env bash
|
||||
# Promote a coulomb repo to Forgejo (tier 2.5): mirror, flip remotes, add ci-smoke.
|
||||
set -euo pipefail
|
||||
|
||||
REPO="${1:?usage: promote-repo-to-forgejo.sh <repo-name> [repo-path]}"
|
||||
REPO_PATH="${2:-$HOME/${REPO}}"
|
||||
ORG=coulomb
|
||||
FORGEJO_API="${FORGEJO_API:-https://forgejo.coulomb.social/api/v1}"
|
||||
TOKEN_FILE="${FORGEJO_TOKEN_FILE:-/tmp/forgejo-tegwick-api-token}"
|
||||
TEMPLATE="${PROMOTE_CI_TEMPLATE:-$HOME/railiance-enablement/workflows/ci-smoke.yaml}"
|
||||
|
||||
if [[ ! -f "${TOKEN_FILE}" ]]; then
|
||||
echo "Missing API token at ${TOKEN_FILE}" >&2
|
||||
exit 1
|
||||
fi
|
||||
TOKEN=$(cat "${TOKEN_FILE}")
|
||||
AUTH=(-H "Authorization: token ${TOKEN}")
|
||||
|
||||
code=$(curl -sS -o /dev/null -w '%{http_code}' "${AUTH[@]}" "${FORGEJO_API}/repos/${ORG}/${REPO}")
|
||||
if [[ "${code}" == "404" ]]; then
|
||||
echo "==> Creating ${ORG}/${REPO} on Forgejo"
|
||||
curl -fsS -X POST "${FORGEJO_API}/orgs/${ORG}/repos" "${AUTH[@]}" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "{\"name\":\"${REPO}\",\"private\":false,\"auto_init\":false}" >/dev/null
|
||||
elif [[ "${code}" == "200" ]]; then
|
||||
echo "==> ${ORG}/${REPO} already exists on Forgejo"
|
||||
else
|
||||
echo "Unexpected API status ${code} for ${ORG}/${REPO}" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cd "${REPO_PATH}"
|
||||
|
||||
mkdir -p .forgejo/workflows
|
||||
if [[ ! -f .forgejo/workflows/ci-smoke.yaml ]]; then
|
||||
cp "${TEMPLATE}" .forgejo/workflows/ci-smoke.yaml
|
||||
git add .forgejo/workflows/ci-smoke.yaml
|
||||
git commit -m "Add Forgejo CI smoke workflow (enablement template)"
|
||||
fi
|
||||
|
||||
if git remote get-url origin 2>/dev/null | grep -q forgejo-remote; then
|
||||
echo "==> Remotes already on Forgejo"
|
||||
else
|
||||
git remote rename origin gitea
|
||||
git remote add origin "forgejo-remote:${ORG}/${REPO}.git"
|
||||
echo "==> Remotes: origin=forgejo-remote, gitea=legacy"
|
||||
fi
|
||||
|
||||
echo "==> Pushing ${REPO_PATH} to Forgejo"
|
||||
git push -u origin main
|
||||
echo "==> Promoted ${REPO}"
|
||||
29
workflows/ci-smoke.yaml
Normal file
29
workflows/ci-smoke.yaml
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
# Canonical CI smoke template (tier 1 routing drill).
|
||||
# Copy to: .forgejo/workflows/ci-smoke.yaml in consumer repos.
|
||||
name: CI Smoke
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
host-smoke:
|
||||
runs-on: self-hosted
|
||||
steps:
|
||||
- name: Routing probe (host runner)
|
||||
run: |
|
||||
set -eu
|
||||
echo "repository=${GITHUB_REPOSITORY:-unknown}"
|
||||
echo "sha=${GITHUB_SHA:-unknown}"
|
||||
echo "runner=${RUNNER_NAME:-unknown}"
|
||||
uname -a
|
||||
|
||||
container-smoke:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Routing probe (container label)
|
||||
run: |
|
||||
set -eu
|
||||
echo "container-smoke ok for ${GITHUB_REPOSITORY:-unknown}"
|
||||
61
workflows/container-build-push-multirepo.yaml
Normal file
61
workflows/container-build-push-multirepo.yaml
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
# Multi-repo Docker build template for tier-3 prep (e.g. state-hub + hub-core).
|
||||
# Copy to: .forgejo/workflows/image.yaml and set PRIMARY_REPO + EXTRA_REPOS.
|
||||
# Uses archive checkout (no actions/checkout; non-root runner has no git).
|
||||
# Dockerfile must reference named contexts, e.g.:
|
||||
# COPY --from=hub_core_src pyproject.toml /tmp/hub-core/pyproject.toml
|
||||
name: Build and Publish Multi-Context Image
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
paths:
|
||||
- ".forgejo/workflows/image.yaml"
|
||||
- "Dockerfile"
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
REGISTRY: forgejo.coulomb.social
|
||||
IMAGE_NAME: coulomb/REPLACE_ME
|
||||
DOCKER_HOST: tcp://127.0.0.1:2375
|
||||
# Space-separated coulomb/repo@context_name entries for extra build contexts.
|
||||
# Example: "coulomb/hub-core@hub_core_src"
|
||||
EXTRA_REPOS: "coulomb/hub-core@hub_core_src"
|
||||
|
||||
jobs:
|
||||
build-and-push:
|
||||
runs-on: container-build
|
||||
steps:
|
||||
- name: Build and push image
|
||||
env:
|
||||
REGISTRY_USER: ${{ secrets.REGISTRY_USER }}
|
||||
REGISTRY_TOKEN: ${{ secrets.REGISTRY_TOKEN }}
|
||||
run: |
|
||||
set -eu
|
||||
REF="${GITHUB_SHA:-main}"
|
||||
mkdir -p buildctx "${HOME}/bin"
|
||||
wget -qO /tmp/primary.tar.gz \
|
||||
"https://forgejo.coulomb.social/${GITHUB_REPOSITORY}/archive/${REF}.tar.gz"
|
||||
tar xzf /tmp/primary.tar.gz -C buildctx --strip-components=1
|
||||
BUILD_ARGS=()
|
||||
for spec in ${EXTRA_REPOS}; do
|
||||
repo="${spec%@*}"
|
||||
ctx="${spec#*@}"
|
||||
extra_ref="${REF}"
|
||||
wget -qO "/tmp/${ctx}.tar.gz" \
|
||||
"https://forgejo.coulomb.social/${repo}/archive/${extra_ref}.tar.gz"
|
||||
mkdir -p "/tmp/ctx-${ctx}"
|
||||
tar xzf "/tmp/${ctx}.tar.gz" -C "/tmp/ctx-${ctx}" --strip-components=1
|
||||
BUILD_ARGS+=(--build-context "${ctx}=/tmp/ctx-${ctx}")
|
||||
done
|
||||
wget -qO- https://download.docker.com/linux/static/stable/x86_64/docker-27.3.1.tgz \
|
||||
| tar xz --strip-components=1 -C "${HOME}/bin" docker/docker
|
||||
export PATH="${HOME}/bin:${PATH}"
|
||||
echo "${REGISTRY_TOKEN}" | docker login "${REGISTRY}" -u "${REGISTRY_USER}" --password-stdin
|
||||
SHORT="${REF:0:7}"
|
||||
IMAGE="${REGISTRY}/${IMAGE_NAME}"
|
||||
docker build "${BUILD_ARGS[@]}" \
|
||||
-t "${IMAGE}:latest" -t "${IMAGE}:main-${SHORT}" buildctx
|
||||
docker push "${IMAGE}:latest"
|
||||
docker push "${IMAGE}:main-${SHORT}"
|
||||
echo "pushed ${IMAGE}:latest and ${IMAGE}:main-${SHORT}"
|
||||
48
workflows/container-build-push.yaml
Normal file
48
workflows/container-build-push.yaml
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
# Canonical single-repo image build template (tier 2).
|
||||
# Copy to: .forgejo/workflows/image.yaml and set IMAGE_NAME.
|
||||
# Requires org secrets: REGISTRY_USER, REGISTRY_TOKEN
|
||||
# Runner label: container-build (DinD sidecar on railiance01-build-01)
|
||||
name: Build and Publish Container Image
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
paths:
|
||||
- ".forgejo/workflows/image.yaml"
|
||||
- "Dockerfile"
|
||||
- "src/**"
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
REGISTRY: forgejo.coulomb.social
|
||||
# Set per repo, e.g. coulomb/key-cape
|
||||
IMAGE_NAME: coulomb/REPLACE_ME
|
||||
DOCKER_HOST: tcp://127.0.0.1:2375
|
||||
|
||||
jobs:
|
||||
build-and-push:
|
||||
runs-on: container-build
|
||||
steps:
|
||||
- name: Build and push image
|
||||
env:
|
||||
REGISTRY_USER: ${{ secrets.REGISTRY_USER }}
|
||||
REGISTRY_TOKEN: ${{ secrets.REGISTRY_TOKEN }}
|
||||
run: |
|
||||
set -eu
|
||||
REF="${GITHUB_SHA:-main}"
|
||||
mkdir -p buildctx "${HOME}/bin"
|
||||
wget -qO /tmp/repo.tar.gz \
|
||||
"https://forgejo.coulomb.social/${GITHUB_REPOSITORY}/archive/${REF}.tar.gz"
|
||||
tar xzf /tmp/repo.tar.gz -C buildctx --strip-components=1
|
||||
wget -qO- https://download.docker.com/linux/static/stable/x86_64/docker-27.3.1.tgz \
|
||||
| tar xz --strip-components=1 -C "${HOME}/bin" docker/docker
|
||||
export PATH="${HOME}/bin:${PATH}"
|
||||
docker version
|
||||
echo "${REGISTRY_TOKEN}" | docker login "${REGISTRY}" -u "${REGISTRY_USER}" --password-stdin
|
||||
SHORT="${REF:0:7}"
|
||||
IMAGE="${REGISTRY}/${IMAGE_NAME}"
|
||||
docker build -t "${IMAGE}:latest" -t "${IMAGE}:main-${SHORT}" buildctx
|
||||
docker push "${IMAGE}:latest"
|
||||
docker push "${IMAGE}:main-${SHORT}"
|
||||
echo "pushed ${IMAGE}:latest and ${IMAGE}:main-${SHORT}"
|
||||
Loading…
Add table
Add a link
Reference in a new issue