From d0162d522204e3062a9d1258732a17128c26a2a5 Mon Sep 17 00:00:00 2001 From: tegwick Date: Fri, 8 May 2026 00:01:40 +0200 Subject: [PATCH 01/10] =?UTF-8?q?chore:=20mark=20T12=20done=20=E2=80=94=20?= =?UTF-8?q?CI=20pipeline=20verified=20end-to-end=20(run=20#2297)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Gitea Actions build-and-deploy workflow ran successfully without manual intervention: checkout → nix build → skopeo push → helm deploy all passed. Co-Authored-By: Claude Sonnet 4.6 --- workplans/IRP-WP-0001-pipeline-validation.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/workplans/IRP-WP-0001-pipeline-validation.md b/workplans/IRP-WP-0001-pipeline-validation.md index aaf7245..33e10a3 100644 --- a/workplans/IRP-WP-0001-pipeline-validation.md +++ b/workplans/IRP-WP-0001-pipeline-validation.md @@ -398,7 +398,7 @@ Verify the full pipeline produced a live application: ```task id: IRP-WP-0001-T12 -status: blocked +status: done priority: low state_hub_task_id: "0bf9c616-54e6-48f3-ae6d-d91a9f7517c9" ``` @@ -450,4 +450,4 @@ Automate the build → push → deploy pipeline via Gitea Actions: | T09 | k3s can pull from HTTP registry | done | | T10 | Pod Running on Railiance01 | done | | T11 | Smoke tests pass; log entry committed | done | -| T12 | CI pipeline automated (optional) | todo | +| T12 | CI pipeline automated (optional) | done | From 537a1d667327039932ab749c37b25414d54f37c1 Mon Sep 17 00:00:00 2001 From: tegwick Date: Mon, 18 May 2026 16:55:42 +0200 Subject: [PATCH 02/10] Refresh agent instruction files --- .claude/rules/architecture.md | 2 +- .claude/rules/first-session.md | 4 +- .claude/rules/repo-boundary.md | 2 +- .claude/rules/repo-identity.md | 3 +- .claude/rules/session-protocol.md | 33 +++++- .claude/rules/workplan-convention.md | 6 + AGENTS.md | 162 +++++++++++++++++++++++++++ 7 files changed, 200 insertions(+), 12 deletions(-) create mode 100644 AGENTS.md diff --git a/.claude/rules/architecture.md b/.claude/rules/architecture.md index 4f6c74c..7c2a645 100644 --- a/.claude/rules/architecture.md +++ b/.claude/rules/architecture.md @@ -5,4 +5,4 @@ ## Quick Reference -`~/the-custodian/state-hub/mcp_server/TOOLS.md` — MCP tool reference +`~/state-hub/mcp_server/TOOLS.md` — MCP tool reference diff --git a/.claude/rules/first-session.md b/.claude/rules/first-session.md index 2513b6f..94b9dc7 100644 --- a/.claude/rules/first-session.md +++ b/.claude/rules/first-session.md @@ -21,7 +21,7 @@ workplans/ihp-railiance-probe-WP-NNNN-.md ← write this first ``` Then register in the hub: ``` -create_workstream(topic_id="(none)", title="...", owner="...", description="...") +create_workstream(topic_id="595afc64-bd28-47bf-aafb-ba230b28371b", title="...", owner="...", description="...") create_task(workstream_id="", title="...", priority="high|medium|low") ``` @@ -30,7 +30,7 @@ create_task(workstream_id="", title="...", priority="high|medium|low") add_progress_event( summary="First session: structured stack into N workstreams, M tasks", event_type="milestone", - topic_id="(none)", + topic_id="595afc64-bd28-47bf-aafb-ba230b28371b", detail={"workstreams": [...], "tasks_created": M} ) ``` diff --git a/.claude/rules/repo-boundary.md b/.claude/rules/repo-boundary.md index f0ab07a..f92d3d8 100644 --- a/.claude/rules/repo-boundary.md +++ b/.claude/rules/repo-boundary.md @@ -4,5 +4,5 @@ This repo owns **ihp-railiance-probe** only. It does not own: diff --git a/.claude/rules/repo-identity.md b/.claude/rules/repo-identity.md index 5dcb307..5c7f5cd 100644 --- a/.claude/rules/repo-identity.md +++ b/.claude/rules/repo-identity.md @@ -1,6 +1,5 @@ -**Purpose:** ihp-railiance-probe — (fill in purpose) +**Purpose:** ihp-railiance-probe - (fill in purpose) **Domain:** stack **Repo slug:** ihp-railiance-probe -**Topic slug:** stack **Topic ID:** 595afc64-bd28-47bf-aafb-ba230b28371b diff --git a/.claude/rules/session-protocol.md b/.claude/rules/session-protocol.md index 5c3dd6d..5569fe2 100644 --- a/.claude/rules/session-protocol.md +++ b/.claude/rules/session-protocol.md @@ -8,24 +8,38 @@ Read the offline-safe brief first — it works without a live hub connection: ```bash cat .custodian-brief.md ``` -Then call the MCP tool for richer cross-domain context (skip if unreachable): +Then call the MCP tool for richer cross-domain context when MCP tools are exposed: ``` get_domain_summary("stack") ``` -If the hub is offline: `cd ~/the-custodian/state-hub && make api` +If MCP tools are unavailable in the current agent session, use the REST API: +```bash +curl -s "http://127.0.0.1:8000/state/summary" | python3 -m json.tool +``` +If the hub is offline: `cd ~/state-hub && make api` **Step 2 — Check inbox** +With MCP tools: ``` get_messages(to_agent="ihp-railiance-probe", unread_only=True) ``` Mark read with `mark_message_read(message_id)`. Reply or act on coordination requests before proceeding. +Without MCP tools: +```bash +curl -s "http://127.0.0.1:8000/messages/?to_agent=ihp-railiance-probe&unread_only=true" \ + | python3 -m json.tool +curl -s -X PATCH "http://127.0.0.1:8000/messages//read" \ + -H "Content-Type: application/json" -d '{}' +``` + **Step 3 — Scan workplans** ```bash ls workplans/ ``` -For each file with `status: active`, note pending `todo`/`in_progress` tasks. +For each file with `status: ready`, `active`, or `blocked`, note pending +`todo`/`in_progress` tasks. **Step 4 — Present brief** @@ -45,18 +59,25 @@ If no workstreams: follow First Session Protocol (`first-session.md`). > are First Session Protocol only. Work structure belongs in repo files (ADR-001). **Session close:** +With MCP tools: ``` -add_progress_event(summary="...", topic_id="(none)", workstream_id="") +add_progress_event(summary="...", topic_id="595afc64-bd28-47bf-aafb-ba230b28371b", workstream_id="") +``` +Without MCP tools: +```bash +curl -s -X POST http://127.0.0.1:8000/progress/ \ + -H "Content-Type: application/json" \ + -d '{"topic_id":"595afc64-bd28-47bf-aafb-ba230b28371b","workstream_id":"","event_type":"note","summary":"what changed","author":"codex"}' ``` If workplan files were modified, ensure the local copy is up to date first: ```bash git -C pull --ff-only -cd ~/the-custodian/state-hub && make fix-consistency REPO=ihp-railiance-probe +cd ~/state-hub && make fix-consistency REPO=ihp-railiance-probe ``` For repos where implementation runs on a remote machine (e.g. CoulombCore), use the combined target which pulls before fixing: ```bash -cd ~/the-custodian/state-hub && make fix-consistency-remote REPO=ihp-railiance-probe +cd ~/state-hub && make fix-consistency-remote REPO=ihp-railiance-probe ``` **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 diff --git a/.claude/rules/workplan-convention.md b/.claude/rules/workplan-convention.md index 12a60e3..8c1e10d 100644 --- a/.claude/rules/workplan-convention.md +++ b/.claude/rules/workplan-convention.md @@ -5,6 +5,12 @@ ID prefix: `IHP-WP` Work items originate as files in this repo **before** being registered in the hub. +Canonical workplan/workstream 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-ihp-railiance-probe-WP-NNNN-.md`. The frontmatter id remains unchanged; the prefix is only for quick visual reference. diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..14e1d70 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,162 @@ +# ihp-railiance-probe — Agent Instructions + +## Repo Identity + +**Purpose:** ihp-railiance-probe - (fill in purpose) + +**Domain:** stack +**Repo slug:** ihp-railiance-probe +**Topic ID:** `595afc64-bd28-47bf-aafb-ba230b28371b` +**Workplan prefix:** `IHP-WP-` + +--- + +## State Hub Integration + +The Custodian State Hub tracks work across all domains. Interact via HTTP REST — +there is no MCP server for Codex agents. + +| Context | URL | +|---------|-----| +| Local workstation | `http://127.0.0.1:8000` | +| Remote via tunnel | `http://127.0.0.1:18000` | + +### Orient at session start + +```bash +# 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=595afc64-bd28-47bf-aafb-ba230b28371b&status=active" \ + | python3 -m json.tool + +# Check inbox +curl -s "http://127.0.0.1:8000/messages/?to_agent=ihp-railiance-probe&unread_only=true" \ + | python3 -m json.tool +``` + +Mark a message read: +```bash +curl -s -X PATCH "http://127.0.0.1:8000/messages//read" \ + -H "Content-Type: application/json" -d '{}' +``` + +### Log progress (required at session close) + +```bash +curl -s -X POST http://127.0.0.1:8000/progress/ \ + -H "Content-Type: application/json" \ + -d '{ + "summary": "what was done", + "event_type": "note", + "author": "codex", + "workstream_id": "", + "task_id": "" + }' +``` + +Omit `workstream_id` / `task_id` when not applicable. + +### Update task status + +```bash +curl -s -X PATCH "http://127.0.0.1:8000/tasks/" \ + -H "Content-Type: application/json" \ + -d '{"status": "in_progress"}' +# values: todo | in_progress | done | blocked +``` + +### Flag a task for human review + +```bash +curl -s -X PATCH "http://127.0.0.1:8000/tasks/" \ + -H "Content-Type: application/json" \ + -d '{"needs_human": true, "intervention_note": "reason"}' +``` + +--- + +## Session Protocol + +**Start:** +1. `cat .custodian-brief.md` — domain goal and open workstreams (offline-safe) +2. Check inbox: `GET /messages/?to_agent=ihp-railiance-probe&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` + +**During work:** +- Update task statuses in workplan files as tasks progress +- Record significant decisions via `POST /decisions/` + +**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`: + ```bash + make fix-consistency REPO=ihp-railiance-probe + ``` + This syncs task status from files into the hub DB. + +--- + +## Workplan Convention (ADR-001) + +Work items originate as files in this repo — not in the hub. The hub is a +read/cache/index layer that rebuilds from files. + +**File location:** `workplans/IHP-WP-NNNN-.md` + +**Archived location:** finished workplans may move to +`workplans/archived/YYMMDD-IHP-WP-NNNN-.md`. The `YYMMDD` prefix is +the completion/archive date; the frontmatter `id` does not change. + +**Ad Hoc Tasks:** small opportunistic fixes discovered during a session use +`workplans/ADHOC-YYYY-MM-DD.md` with task ids `ADHOC-YYYY-MM-DD-T01`, etc. Use +this only for low-risk work completed directly; create a normal workplan for +anything needing analysis, design, approval, dependencies, or multiple phases. + +**Frontmatter:** + +```yaml +--- +id: IHP-WP-NNNN +type: workplan +title: "..." +domain: stack +repo: ihp-railiance-probe +status: proposed | ready | active | blocked | backlog | finished | archived +owner: codex +topic_slug: ... +created: "YYYY-MM-DD" +updated: "YYYY-MM-DD" +state_hub_workstream_id: "" # written by fix-consistency — do not edit +--- +``` + +Use `proposed` for a new draft, `ready` after review against current repo +state, and `finished` after implementation. `stalled` and `needs_review` are +derived health labels, not frontmatter statuses. + +**Task block format** (one per `##` section): + +``` +## Task Title + +` ` `task +id: IHP-WP-NNNN-T01 +status: todo | in_progress | done | blocked +priority: high | medium | low +state_hub_task_id: "" # written by fix-consistency — do not edit +` ` ` + +Task description text. +``` + +Status progression: `todo` → `in_progress` → `done` (or `blocked`) + +To create a new workplan: +1. Write the file following the format above +2. Notify the custodian operator to run `make fix-consistency REPO=ihp-railiance-probe` + (or send a message to the hub agent via `POST /messages/`) From b74a501e7ce12e850270441d0b4167ece27b1489 Mon Sep 17 00:00:00 2001 From: tegwick Date: Fri, 5 Jun 2026 00:56:34 +0200 Subject: [PATCH 03/10] Document probe scope --- SCOPE.md | 185 +++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 124 insertions(+), 61 deletions(-) diff --git a/SCOPE.md b/SCOPE.md index d48e39a..3fbe07a 100644 --- a/SCOPE.md +++ b/SCOPE.md @@ -1,137 +1,200 @@ # SCOPE -> This file helps you quickly understand what this repository is about, -> when it is relevant, and when it is not. -> It is intentionally lightweight and may be incomplete. +This file defines what `ihp-railiance-probe` owns, when to use it, and where +its boundaries stop. + +Last reviewed: 2026-06-04 --- ## One-liner - - +A minimal IHP-on-Railiance canary application that proves the full path from +Nix production build to Gitea OCI image, Helm deployment on Railiance01, and +live HTTP smoke verification. --- ## Core Idea - - +`ihp-railiance-probe` is intentionally small. It exists to make expensive +IHP/GHC/Nix/deployment failures cheap to reproduce before larger applications +such as `inter-hub` rely on the same path. + +The repo owns a tiny IHP app, the production build shape, a Helm deployment +chart, and the evidence trail for end-to-end validation. Its value is not +business functionality; its value is proving that the IHP workload pipeline is +healthy enough for real apps to use. --- ## In Scope - - - -- -- -- +- Minimal IHP application code: + - `Web/Controller/Health.hs` for `GET /healthz -> ok`; + - `Web/Controller/Probes.hs` for basic `probes` CRUD; + - routes, views, schema, and fixtures needed for the small probe surface. +- Minimal database schema in `Application/Schema.sql`: + - `uuid-ossp` extension; + - one `probes` table with `id`, `name`, and `created_at`. +- Test-first validation surface: + - `Test/ProbeControllerSpec.hs`; + - `Test/Main.hs`; + - Hspec checks for `/probes` and `/healthz`. +- IHP/Nix production build configuration: + - `flake.nix`; + - IHP v1.5 inputs; + - `nix build .#docker`; + - low-memory GHC runtime settings and the GHC 9.10.3 mitigation overlay. +- Kubernetes deployment artifact: + - Helm chart under `chart/`; + - deployment, service, ingress, image settings, resource limits, and + `/healthz` liveness probe. +- Pipeline documentation and evidence: + - `INTENT.md`; + - `DeploymentBlueprint.md`; + - `PIPELINE_LOG.md`; + - completed workplan `workplans/IRP-WP-0001-pipeline-validation.md`. --- ## Out of Scope - - - -- -- -- +- Production business functionality. This is a probe, not an application + product. +- `inter-hub` source code, domain model, features, or release ownership. +- Generic IHP framework maintenance. +- Railiance OS provisioning, Kubernetes runtime setup, and shared platform + services. +- Long-term ownership of Gitea, registries, PostgreSQL, ingress controllers, or + k3s cluster configuration. +- Secret custody. The chart references an environment Secret name, but this + repo must not store live secret values. +- A general-purpose application template. Lessons may inform templates + elsewhere, but this repo stays a small validation target. --- ## Relevant When - - -- -- -- +- Validating that an IHP project can build a production OCI image with the + current Nix/IHP/GHC stack. +- Checking whether known GHC 9.10.3 production-build mitigations still work. +- Proving the Gitea container registry push path for an IHP image. +- Testing that Railiance01 can pull and run the image from the Gitea registry. +- Verifying Helm deployment, service routing, ingress, and `/healthz` behavior + for an IHP workload. +- Rehearsing the path before promoting a larger IHP app. --- ## Not Relevant When - - -- -- -- +- You need application features or user-facing product behavior. +- You need to debug the internals of `inter-hub`. +- You are provisioning hosts, installing k3s, or managing cluster-level addons. +- You are designing shared Railiance platform services such as databases, + secret management, object storage, or caches. +- You need a durable production service with real data and recovery guarantees. +- You need canonical CI/CD or developer enablement templates rather than this + specific probe implementation. --- ## Current State - +- Status: validated canary. +- Implementation: minimal IHP app, schema, health endpoint, probe CRUD, tests, + Nix Docker image build config, Helm chart, deployment blueprint, and pipeline + log are present. +- Stability: suitable as a regression probe; intentionally narrow. +- Usage: two end-to-end pipeline runs are recorded in `PIPELINE_LOG.md` + (`e372a0c` on 2026-05-03 and `511a503` on 2026-05-07), both with build, + push, deploy, and smoke marked PASS. -- Status: -- Implementation: -- Stability: -- Usage: - - +The completed workplan records Gitea Actions automation as done, but the +repository surface visible here does not currently include a +`.gitea/workflows/` file. Treat that as a documentation/state gap to verify +before relying on unattended CI. --- ## How It Fits - - - Upstream dependencies: + IHP v1.5, GHC 9.10.3, Nix/devenv, haskelseed build host, Gitea OCI registry, + Railiance01/k3s, Helm, and a PostgreSQL-compatible `DATABASE_URL`. - Downstream consumers: + humans and agents validating the IHP-on-Railiance release path; larger IHP + applications that want confidence before promotion. - Often used with: + `inter-hub`, `railiance-apps`, `railiance-enablement`, Gitea on CoulombCore, + and Railiance01. --- ## Terminology - - - - Preferred terms: + probe, canary, pipeline validation, smoke test, IHP-on-Railiance. - Also known as: + IHP deployment probe, Railiance IHP canary. - Potentially confusing terms: + this repo is "upstream in confidence" from `inter-hub`, not a source-code + dependency of it. --- ## Related / Overlapping Repositories - - - -- +- `inter-hub` - the larger IHP workload whose expensive build/deployment + failures motivated this small probe. +- `railiance-apps` - owns S5 application release patterns and app workload + operations for Railiance; this repo is a source workload used to validate an + IHP path into that layer. +- `railiance-enablement` - eventual home for reusable CI/CD, templates, and + developer delivery paths that this probe may inform. +- `railiance-cluster` - owns Kubernetes runtime concerns such as k3s and + cluster-level registry configuration. +- `railiance-platform` - owns shared stateful services such as databases and + secrets consumed by workloads. --- ## Getting Oriented - - -- Start with: -- Key files / directories: -- Entry points: +1. Read `INTENT.md` to understand why the repo exists. +2. Read `DeploymentBlueprint.md` for the full workstation -> haskelseed -> + Gitea registry -> Railiance01 flow. +3. Read `PIPELINE_LOG.md` for recorded successful pipeline runs. +4. Inspect `flake.nix` for the production image build and GHC mitigations. +5. Inspect `chart/` for Kubernetes deployment shape. +6. Inspect `Web/Controller/Health.hs`, `Web/Controller/Probes.hs`, and + `Test/ProbeControllerSpec.hs` for the app and smoke-test surface. +7. Inspect `workplans/IRP-WP-0001-pipeline-validation.md` for the completed + validation sequence and operational caveats. --- ## Provided Capabilities - - - - - --- ## Notes - +The README still looks like the original seed template. Use `INTENT.md`, +`DeploymentBlueprint.md`, and this file as the current orientation documents. From 11dc2baaf2b43ee424ca2e2a188b89cd35d68353 Mon Sep 17 00:00:00 2001 From: tegwick Date: Tue, 16 Jun 2026 01:52:50 +0200 Subject: [PATCH 04/10] Add capability registry scaffold (REUSE-WP-0014-T04 B02) Empty helix_forge registry layout for federation publishing. --- registry/README.md | 12 ++++++++++++ registry/capabilities/.gitkeep | 0 registry/indexes/capabilities.yaml | 4 ++++ 3 files changed, 16 insertions(+) create mode 100644 registry/README.md create mode 100644 registry/capabilities/.gitkeep create mode 100644 registry/indexes/capabilities.yaml diff --git a/registry/README.md b/registry/README.md new file mode 100644 index 0000000..569abe9 --- /dev/null +++ b/registry/README.md @@ -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`. diff --git a/registry/capabilities/.gitkeep b/registry/capabilities/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/registry/indexes/capabilities.yaml b/registry/indexes/capabilities.yaml new file mode 100644 index 0000000..f944e47 --- /dev/null +++ b/registry/indexes/capabilities.yaml @@ -0,0 +1,4 @@ +version: 1 +updated: '2026-06-16' +domain: helix_forge +capabilities: [] From 84b1a3d23b2fee7865a8cc746e928a1bd9e27c62 Mon Sep 17 00:00:00 2001 From: tegwick Date: Thu, 18 Jun 2026 22:48:38 +0200 Subject: [PATCH 05/10] Add credential routing instructions for all agent runtimes Propagate shared credential-routing section (Codex, Claude, Grok, llm-connect) from state-hub template via scripts/propagate_credential_routing.py. --- .claude/rules/credential-routing.md | 50 +++++++++++++++++++++++++++ AGENTS.md | 52 +++++++++++++++++++++++++++++ CLAUDE.md | 1 + 3 files changed, 103 insertions(+) create mode 100644 .claude/rules/credential-routing.md diff --git a/.claude/rules/credential-routing.md b/.claude/rules/credential-routing.md new file mode 100644 index 0000000..9870915 --- /dev/null +++ b/.claude/rules/credential-routing.md @@ -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 "" --json +warden route show --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=ihp-railiance-probe` is for coordination, not secret vending | +| **Claude Code** (MCP when available) | `get_domain_summary("custodian")` for workstreams; **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` \ No newline at end of file diff --git a/AGENTS.md b/AGENTS.md index 14e1d70..dee747e 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -101,6 +101,58 @@ curl -s -X PATCH "http://127.0.0.1:8000/tasks/" \ --- +## 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 "" --json +warden route show --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=ihp-railiance-probe` is for coordination, not secret vending | +| **Claude Code** (MCP when available) | `get_domain_summary("custodian")` for workstreams; **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` +--- + ## Workplan Convention (ADR-001) Work items originate as files in this repo — not in the hub. The hub is a diff --git a/CLAUDE.md b/CLAUDE.md index 3cd517a..82ab8ba 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -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 From 049ae0abe3b22b8de227dac400c1136efe5afd2b Mon Sep 17 00:00:00 2001 From: tegwick Date: Mon, 22 Jun 2026 17:47:37 +0200 Subject: [PATCH 06/10] Add .repo-classification.yaml (CUST-WP-0050 T11 agent first-pass) --- .repo-classification.yaml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 .repo-classification.yaml diff --git a/.repo-classification.yaml b/.repo-classification.yaml new file mode 100644 index 0000000..28406fa --- /dev/null +++ b/.repo-classification.yaml @@ -0,0 +1,18 @@ +repo_classification: + standard: Repo Classification Standard + version: '1.0' + classified_at: '2026-06-22' + classified_by: agent + category: project + domain: infotech + secondary_domains: [] + capability_tags: + - platform + - operations + business_stake: + - technology + - product + - operations + business_mechanics: + - coordination + - operation From 994c764d37e50444602ecad926d4d96c5e9119c0 Mon Sep 17 00:00:00 2001 From: tegwick Date: Mon, 22 Jun 2026 23:16:25 +0200 Subject: [PATCH 07/10] Normalize agent instructions and workplan frontmatter (STATE-WP-0067) - Align agent files with on-disk workplan prefixes (infer from workplan ids) - Set workplan domain to registered domain_slug; add topic_slug where applicable - Repair frontmatter delimiter formatting; migrate legacy task status literals - Regenerate AGENTS.md, CLAUDE.md, and .claude/rules from State Hub templates --- .claude/rules/first-session.md | 14 +++++------ .claude/rules/repo-identity.md | 4 ++-- .claude/rules/session-protocol.md | 13 +++++----- .claude/rules/workplan-convention.md | 18 +++++++++++--- AGENTS.md | 25 ++++++++++++-------- workplans/IRP-WP-0001-pipeline-validation.md | 2 +- 6 files changed, 47 insertions(+), 29 deletions(-) diff --git a/.claude/rules/first-session.md b/.claude/rules/first-session.md index 94b9dc7..f364a74 100644 --- a/.claude/rules/first-session.md +++ b/.claude/rules/first-session.md @@ -1,11 +1,11 @@ ## First Session Protocol -Triggered when `get_domain_summary("stack")` shows **no workstreams**. +Triggered when `get_domain_summary("infotech")` shows **no workstreams**. The project is registered but work has not yet been structured. **Step 1 — Read, don't write** -- `~/the-custodian/canon/projects/stack/project_charter_v0.1.md` — purpose, scope -- `~/the-custodian/canon/projects/stack/roadmap_v0.1.md` — planned phases +- `~/the-custodian/canon/projects/infotech/project_charter_v0.1.md` — purpose, scope +- `~/the-custodian/canon/projects/infotech/roadmap_v0.1.md` — planned phases - Scan repo root: README, directory structure, existing code or docs **Step 2 — Survey in-progress work** @@ -17,20 +17,20 @@ roadmap phase. **Wait for approval before creating.** **Step 4 — Create workplan file first, then DB record (ADR-001)** ``` -workplans/ihp-railiance-probe-WP-NNNN-.md ← write this first +workplans/IRP-WP-NNNN-.md ← write this first ``` Then register in the hub: ``` -create_workstream(topic_id="595afc64-bd28-47bf-aafb-ba230b28371b", title="...", owner="...", description="...") +create_workstream(topic_id="cee7bedf-2b48-46ef-8601-006474f2ad7a", title="...", owner="...", description="...") create_task(workstream_id="", title="...", priority="high|medium|low") ``` **Step 5 — Record the setup** ``` add_progress_event( - summary="First session: structured stack into N workstreams, M tasks", + summary="First session: structured infotech into N workstreams, M tasks", event_type="milestone", - topic_id="595afc64-bd28-47bf-aafb-ba230b28371b", + topic_id="cee7bedf-2b48-46ef-8601-006474f2ad7a", detail={"workstreams": [...], "tasks_created": M} ) ``` diff --git a/.claude/rules/repo-identity.md b/.claude/rules/repo-identity.md index 5c7f5cd..9c1b37b 100644 --- a/.claude/rules/repo-identity.md +++ b/.claude/rules/repo-identity.md @@ -1,5 +1,5 @@ **Purpose:** ihp-railiance-probe - (fill in purpose) -**Domain:** stack +**Domain:** infotech **Repo slug:** ihp-railiance-probe -**Topic ID:** 595afc64-bd28-47bf-aafb-ba230b28371b +**Topic ID:** cee7bedf-2b48-46ef-8601-006474f2ad7a diff --git a/.claude/rules/session-protocol.md b/.claude/rules/session-protocol.md index 5569fe2..b383a14 100644 --- a/.claude/rules/session-protocol.md +++ b/.claude/rules/session-protocol.md @@ -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("stack") +get_domain_summary("infotech") ``` 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//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 `stack` — title, task counts, blocking decisions +1. **Active workstreams** for `infotech` — title, task counts, blocking decisions 2. **Pending tasks** from `workplans/` + any `[repo:ihp-railiance-probe]` hub tasks 3. **Goal guidance** — if `goal_guidance` in summary: - `needs_workplan`: surface as top action — *"Repo goal '{title}' has no workplan yet"* @@ -61,13 +62,13 @@ If no workstreams: follow First Session Protocol (`first-session.md`). **Session close:** With MCP tools: ``` -add_progress_event(summary="...", topic_id="595afc64-bd28-47bf-aafb-ba230b28371b", workstream_id="") +add_progress_event(summary="...", topic_id="cee7bedf-2b48-46ef-8601-006474f2ad7a", workstream_id="") ``` Without MCP tools: ```bash curl -s -X POST http://127.0.0.1:8000/progress/ \ -H "Content-Type: application/json" \ - -d '{"topic_id":"595afc64-bd28-47bf-aafb-ba230b28371b","workstream_id":"","event_type":"note","summary":"what changed","author":"codex"}' + -d '{"topic_id":"cee7bedf-2b48-46ef-8601-006474f2ad7a","workstream_id":"","event_type":"note","summary":"what changed","author":"codex"}' ``` If workplan files were modified, ensure the local copy is up to date first: ```bash diff --git a/.claude/rules/workplan-convention.md b/.claude/rules/workplan-convention.md index 8c1e10d..d72e66a 100644 --- a/.claude/rules/workplan-convention.md +++ b/.claude/rules/workplan-convention.md @@ -1,7 +1,7 @@ ## Workplan Convention (ADR-001) -File location: `workplans/ihp-railiance-probe-WP-NNNN-.md` -ID prefix: `IHP-WP` +File location: `workplans/IRP-WP-NNNN-.md` +ID prefix: `IRP-WP-` Work items originate as files in this repo **before** being registered in the hub. @@ -12,7 +12,7 @@ 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-ihp-railiance-probe-WP-NNNN-.md`. The frontmatter id remains +prefix: `YYMMDD-IRP-WP-NNNN-.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**: @@ -25,4 +25,16 @@ Ecosystem todos from other agents arrive as `[repo:ihp-railiance-probe]` hub tas visible at session start. Pick one up by creating the workplan file, then registering the workstream. +Task blocks use this shape: + +```task +id: IRP-WP-NNNN-T01 +status: wait | todo | progress | done | cancel +priority: high | medium | low +state_hub_task_id: "" # 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. + diff --git a/AGENTS.md b/AGENTS.md index dee747e..8dee763 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -4,10 +4,10 @@ **Purpose:** ihp-railiance-probe - (fill in purpose) -**Domain:** stack +**Domain:** infotech **Repo slug:** ihp-railiance-probe -**Topic ID:** `595afc64-bd28-47bf-aafb-ba230b28371b` -**Workplan prefix:** `IHP-WP-` +**Topic ID:** `cee7bedf-2b48-46ef-8601-006474f2ad7a` +**Workplan prefix:** `IRP-WP-` --- @@ -28,7 +28,7 @@ there is no MCP server for Codex agents. cat .custodian-brief.md # Active workstreams for this domain -curl -s "http://127.0.0.1:8000/workstreams/?topic_id=595afc64-bd28-47bf-aafb-ba230b28371b&status=active" \ +curl -s "http://127.0.0.1:8000/workstreams/?topic_id=cee7bedf-2b48-46ef-8601-006474f2ad7a&status=active" \ | python3 -m json.tool # Check inbox @@ -63,8 +63,8 @@ Omit `workstream_id` / `task_id` when not applicable. ```bash curl -s -X PATCH "http://127.0.0.1:8000/tasks/" \ -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 @@ -83,7 +83,7 @@ curl -s -X PATCH "http://127.0.0.1:8000/tasks/" \ 1. `cat .custodian-brief.md` — domain goal and open workstreams (offline-safe) 2. Check inbox: `GET /messages/?to_agent=ihp-railiance-probe&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 @@ -151,6 +151,11 @@ every repo's agent instructions because it is high-frequency, high-risk, and eas get wrong. **Canon:** `~/ops-warden/wiki/CredentialRouting.md` · catalog `~/ops-warden/registry/routing/catalog.yaml` + + + + --- ## Workplan Convention (ADR-001) @@ -176,7 +181,7 @@ anything needing analysis, design, approval, dependencies, or multiple phases. id: IHP-WP-NNNN type: workplan title: "..." -domain: stack +domain: infotech repo: ihp-railiance-probe status: proposed | ready | active | blocked | backlog | finished | archived owner: codex @@ -198,7 +203,7 @@ derived health labels, not frontmatter statuses. ` ` `task id: IHP-WP-NNNN-T01 -status: todo | in_progress | done | blocked +status: wait | todo | progress | done | cancel priority: high | medium | low state_hub_task_id: "" # written by fix-consistency — do not edit ` ` ` @@ -206,7 +211,7 @@ state_hub_task_id: "" # 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 diff --git a/workplans/IRP-WP-0001-pipeline-validation.md b/workplans/IRP-WP-0001-pipeline-validation.md index 33e10a3..146c135 100644 --- a/workplans/IRP-WP-0001-pipeline-validation.md +++ b/workplans/IRP-WP-0001-pipeline-validation.md @@ -2,7 +2,7 @@ id: IRP-WP-0001 type: workplan title: "ihp-railiance-probe — Full Pipeline Validation" -domain: stack +domain: infotech repo: ihp-railiance-probe status: done owner: tegwick From 8a7b8fd16568b5b71ee8db20eec95816030b5382 Mon Sep 17 00:00:00 2001 From: tegwick Date: Mon, 22 Jun 2026 23:22:30 +0200 Subject: [PATCH 08/10] chore(consistency): sync task status from DB [auto] Updated by fix-consistency on 2026-06-22: - update .custodian-brief.md for ihp-railiance-probe --- .custodian-brief.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.custodian-brief.md b/.custodian-brief.md index 0409a9d..9b2012b 100644 --- a/.custodian-brief.md +++ b/.custodian-brief.md @@ -1,8 +1,8 @@ # Custodian Brief — ihp-railiance-probe -**Domain:** stack -**Last synced:** 2026-05-07 02:12 UTC +**Domain:** infotech +**Last synced:** 2026-06-22 21:22 UTC **State Hub:** http://127.0.0.1:8000 *(adjust if running on a remote machine)* ## Active Workstreams @@ -13,6 +13,6 @@ ## MCP Orientation (when available) If the state-hub MCP server is reachable, call: -`get_domain_summary("stack")` +`get_domain_summary("infotech")` This provides richer cross-domain context. If the MCP call fails, use this file as your orientation source. From 599edc9aa2247554b78396c7fe1d242ee35b6a1e Mon Sep 17 00:00:00 2001 From: tegwick Date: Mon, 6 Jul 2026 18:50:37 +0200 Subject: [PATCH 09/10] Add registry/NO_CAPABILITIES.md (reuse-surface REUSE-WP-0017-T03) Reviewed for the reuse-surface capability registry coverage campaign; no reusable capability to register at this time. See file for rationale. Co-Authored-By: Claude Sonnet 5 --- registry/NO_CAPABILITIES.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 registry/NO_CAPABILITIES.md diff --git a/registry/NO_CAPABILITIES.md b/registry/NO_CAPABILITIES.md new file mode 100644 index 0000000..d9445b5 --- /dev/null +++ b/registry/NO_CAPABILITIES.md @@ -0,0 +1,15 @@ +--- +repo: ihp-railiance-probe +reason: > + Self-described in its own INTENT as a probe, not a product — a pipeline-validation canary app, not intended for reuse. +reviewed: "2026-07-06" +reviewed_by: claude-code +revisit: > + Revisit only if the probe is promoted to a maintained product. +--- + +# No reusable capability + +This repo was reviewed for the `reuse-surface` capability registry +(REUSE-WP-0017 coverage campaign) and has no capability to register at this +time. See the `reason` field above. From efe88a01335753cba849558de705955a2b5ec62e Mon Sep 17 00:00:00 2001 From: tegwick Date: Wed, 8 Jul 2026 00:09:08 +0200 Subject: [PATCH 10/10] Add Forgejo CI smoke workflow (enablement template) --- .forgejo/workflows/ci-smoke.yaml | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 .forgejo/workflows/ci-smoke.yaml diff --git a/.forgejo/workflows/ci-smoke.yaml b/.forgejo/workflows/ci-smoke.yaml new file mode 100644 index 0000000..bd44c56 --- /dev/null +++ b/.forgejo/workflows/ci-smoke.yaml @@ -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}" \ No newline at end of file