refactor(org): update container registry, FQDNs, and add agent UUIDs
- Migrate container registry from ghcr.io to git.farh.net - Update environment FQDNs: cartsnitch.farh.net → cartsnitch.com, etc. - Add UUIDs to all agent role references for handoff protocol accuracy - Add Agent Roster table to CLAUDE.md for quick reference Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -9,16 +9,29 @@ This is the **CartSnitch org-level governance repository** — it contains opera
|
|||||||
- `skills/safety/` — Non-negotiable rules: secret handling, SealedSecrets workflow, kubectl scope limits, destructive-action gating
|
- `skills/safety/` — Non-negotiable rules: secret handling, SealedSecrets workflow, kubectl scope limits, destructive-action gating
|
||||||
- `skills/coding-standards/` — Engineering quality bar, priority ordering, test requirements, task decomposition template
|
- `skills/coding-standards/` — Engineering quality bar, priority ordering, test requirements, task decomposition template
|
||||||
|
|
||||||
|
## Safety (Non-Negotiable)
|
||||||
|
|
||||||
|
These rules apply without exception:
|
||||||
|
|
||||||
|
- **Never exfiltrate secrets.** API keys, tokens, PEM files, database credentials, kubeconfig contents — never log, comment, or return these in any output.
|
||||||
|
- **Never kubectl apply/create secret against production** (`cartsnitch` namespace). All changes go through `cartsnitch/infra` via PR. Flux manages production.
|
||||||
|
- **Never commit plaintext secrets.** Use Bitnami Sealed Secrets (`kubeseal`). No plain Kubernetes secrets at any environment.
|
||||||
|
- **Seek board approval for destructive actions.** Deleting resources, dropping tables, wiping namespaces, force-pushing, resetting git history — use `request_board_approval`.
|
||||||
|
- **Never run `tofu` directly.** Terraform goes through the Flux OpenTofu Controller via PR to `cartsnitch/infra`.
|
||||||
|
- **If uncertain, stop.** Post a comment explaining what you're about to do and why, set issue to `blocked`, and escalate.
|
||||||
|
|
||||||
## Key Operational Procedures
|
## Key Operational Procedures
|
||||||
|
|
||||||
### Gitea authentication
|
### Gitea authentication
|
||||||
Use the `GITEA_TOKEN` environment variable (already set in the agent environment). Use the **`tea`** CLI for all Gitea/Git operations (e.g., `tea issue list`, `tea pr create`). Re-invoke on 401.
|
Use the `GITEA_TOKEN` environment variable (already set in the agent environment). Use the **`tea`** CLI for all Gitea/Git operations (e.g., `tea issue list`, `tea pr create`). Re-invoke on 401.
|
||||||
|
|
||||||
|
Gitea is the **primary source of truth**. Every Paperclip issue must have a corresponding Gitea issue.
|
||||||
|
|
||||||
### Handoff protocol (mandatory)
|
### Handoff protocol (mandatory)
|
||||||
Every handoff to another agent requires all three steps:
|
Every handoff to another agent requires all three steps:
|
||||||
1. `PATCH /api/issues/{id}` with `assigneeAgentId: "<target-agent-uuid>"` (mentioning is NOT a handoff)
|
1. `PATCH /api/issues/{id}` with `assigneeAgentId: "<target-agent-uuid>"` (mentioning is NOT a handoff)
|
||||||
2. Set `status: "todo"` — never `in_review` or `backlog`
|
2. Set `status: "todo"` — never `in_review` or `backlog`
|
||||||
3. Call `POST /api/issues/{issueId}/release` with proper headers
|
3. Call `POST /api/issues/{issueId}/release` with headers `Authorization: Bearer $PAPERCLIP_API_KEY, X-Paperclip-Run-Id: $PAPERCLIP_RUN_ID`
|
||||||
|
|
||||||
### Gitea-origin issue policy
|
### Gitea-origin issue policy
|
||||||
If a task has `originKind: "gitea"`, do not begin work — create a board approval first via `POST /api/companies/{companyId}/approvals`. Set issue to `blocked` until approved.
|
If a task has `originKind: "gitea"`, do not begin work — create a board approval first via `POST /api/companies/{companyId}/approvals`. Set issue to `blocked` until approved.
|
||||||
@@ -27,20 +40,23 @@ If a task has `originKind: "gitea"`, do not begin work — create a board approv
|
|||||||
|
|
||||||
| Environment | Namespace | FQDN | kubectl access |
|
| Environment | Namespace | FQDN | kubectl access |
|
||||||
|-------------|-----------|------|----------------|
|
|-------------|-----------|------|----------------|
|
||||||
| Dev | `cartsnitch-dev` | `cartsnitch.dev.farh.net` | Full read/write |
|
| Dev | `cartsnitch-dev` | `dev.cartsnitch.com` | Full read/write |
|
||||||
| UAT | `cartsnitch-uat` | `cartsnitch.uat.farh.net` | Full read/write |
|
| UAT | `cartsnitch-uat` | `uat.cartsnitch.com` | Full read/write |
|
||||||
| Production | `cartsnitch` | `cartsnitch.farh.net` | Read-only |
|
| Production | `cartsnitch` | `cartsnitch.com` | Read-only |
|
||||||
|
|
||||||
**Production is Flux-managed.** Never `kubectl apply` or `kubectl create secret` against `cartsnitch`. All changes go through `cartsnitch/infra` via PR.
|
**Production is Flux-managed.** Never `kubectl apply` or `kubectl create secret` against `cartsnitch`. All changes go through `cartsnitch/infra` via PR.
|
||||||
|
|
||||||
|
**Gateways:** `istio-external` (public) and `istio-internal` (internal) in `gateway-system`.
|
||||||
|
|
||||||
## Canonical Toolchain (policy-mandated, no alternatives)
|
## Canonical Toolchain (policy-mandated, no alternatives)
|
||||||
|
|
||||||
- **Secret management:** Bitnami Sealed Secrets (`kubeseal`) — no plain Kubernetes secrets
|
- **Secret management:** Bitnami Sealed Secrets (`kubeseal`) — no plain Kubernetes secrets
|
||||||
- **Database:** CloudNativePG Operator (Postgres)
|
- **Database:** CloudNativePG Operator (Postgres)
|
||||||
- **Cache/pub-sub:** DragonflyDB Operator
|
- **Cache/pub-sub:** DragonflyDB Operator
|
||||||
- **Authentication:** Better-Auth + Google + Apple + Authentik OIDC — never build custom auth
|
- **Authentication:** Better-Auth + Google + Apple + Authentik OIDC at `https://auth.farh.net` — never build custom auth
|
||||||
- **Dependency updates:** Mend Renovate — **Dependabot is not used**
|
- **Dependency updates:** Mend Renovate — **Dependabot is not used**
|
||||||
- **Browser automation:** Playwright MCP server (`http://playwright:8931/mcp`) — target dev only, never production
|
- **Browser automation:** Playwright MCP server (`http://playwright:8931/mcp`) — target dev only, never production
|
||||||
|
- **Container registry:** `git.farh.net/cartsnitch/<service>` only — never Docker Hub for first-party images
|
||||||
|
|
||||||
## Branch & Merge Policy
|
## Branch & Merge Policy
|
||||||
|
|
||||||
@@ -53,10 +69,54 @@ If a task has `originKind: "gitea"`, do not begin work — create a board approv
|
|||||||
|
|
||||||
Set `modelProfile: "cheap"` only for mechanical refactors, information lookups, and well-specified bounded updates. Leave unset for anything requiring judgment. When in doubt, leave it unset.
|
Set `modelProfile: "cheap"` only for mechanical refactors, information lookups, and well-specified bounded updates. Leave unset for anything requiring judgment. When in doubt, leave it unset.
|
||||||
|
|
||||||
|
## Task Decomposition Template
|
||||||
|
|
||||||
|
When delegating tasks to other agents, structure them like this:
|
||||||
|
|
||||||
|
```
|
||||||
|
## What
|
||||||
|
[One sentence: the specific action to take]
|
||||||
|
|
||||||
|
## Where
|
||||||
|
[Exact repo, branch, file paths]
|
||||||
|
|
||||||
|
## Why
|
||||||
|
[One sentence: business/technical reason]
|
||||||
|
|
||||||
|
## How
|
||||||
|
[Step-by-step instructions, no ambiguity]
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
- [ ] [Specific, verifiable condition]
|
||||||
|
|
||||||
|
## Context
|
||||||
|
[Code snippets, links, or prior decisions needed to complete the task]
|
||||||
|
```
|
||||||
|
|
||||||
|
## Code Review Tone
|
||||||
|
|
||||||
|
Hold a high bar. PRs with obvious mistakes, missing tests, hardcoded values, or policy violations get firm, specific review comments citing what's wrong and what the fix is. Cite the file and line. Don't sugarcoat — but be professional and constructive.
|
||||||
|
|
||||||
## SDLC Phase Summary
|
## SDLC Phase Summary
|
||||||
|
|
||||||
1. **Dev** — Engineer → PR → QA (Checkout Charlie) → CTO (Savannah Savings) → CTO merges
|
1. **Dev** — Engineer → PR → QA (Checkout Charlie `9b6012d0-0406-417e-bb22-78266a6e7f77`) → CTO (Savannah Savings `6ec1a5a9-113c-430b-90e6-260d60d79e1d`) → CTO merges
|
||||||
2. **UAT** — CTO opens `dev→uat` PR → deploys → Deal Dottie regression → Stockboy Steve security review
|
2. **UAT** — CTO opens `dev→uat` PR → deploys → Deal Dottie (`161fb3bb-0332-4381-b67d-7c4b92a91133`) regression → Stockboy Steve (`d59d4b24-3cc3-4616-a23a-2b4776a489ca`) security review
|
||||||
3. **Production** — CEO (Coupon Carl) reviews and merges `uat→main` → auto-deploy via Flux
|
3. **Production** — CEO (Coupon Carl `cd91facf-8f4c-4cbd-b8d8-b48da5b50727`) reviews and merges `uat→main` → auto-deploy via Flux
|
||||||
|
|
||||||
If any phase fails, work returns to the engineer (CTO cascades).
|
If any phase fails, work returns to the engineer (CTO cascades).
|
||||||
|
|
||||||
|
## Agent Roster
|
||||||
|
|
||||||
|
| Agent | Role | UUID |
|
||||||
|
|-------|------|------|
|
||||||
|
| Coupon Carl | CEO | `cd91facf-8f4c-4cbd-b8d8-b48da5b50727` |
|
||||||
|
| Savannah Savings | CTO | `6ec1a5a9-113c-430b-90e6-260d60d79e1d` |
|
||||||
|
| Markdown Martha | CMO | `46614fb2-6d29-4ea3-bc46-4a3b94086e3c` |
|
||||||
|
| Deal Dottie | UAT | `161fb3bb-0332-4381-b67d-7c4b92a91133` |
|
||||||
|
| Stockboy Steve | Security | `d59d4b24-3cc3-4616-a23a-2b4776a489ca` |
|
||||||
|
| Barcode Betty | Engineer | `1ba0c654-eba6-4d17-8c8e-b0a923ead8e6` |
|
||||||
|
| Checkout Charlie | QA | `9b6012d0-0406-417e-bb22-78266a6e7f77` |
|
||||||
|
|
||||||
|
## Versioning
|
||||||
|
|
||||||
|
CartSnitch CI uses **CalVer** (`YYYY.MM.DD[.N]`) for image tags. CI also publishes `latest` and `sha-<hash>`. Do not introduce other versioning schemes for application images.
|
||||||
@@ -56,7 +56,7 @@ CartSnitch CI uses **CalVer** (`YYYY.MM.DD[.N]`) for image tags. The CI also pub
|
|||||||
|
|
||||||
## Container images
|
## Container images
|
||||||
|
|
||||||
Push to `ghcr.io/cartsnitch/<service>` only. Never Docker Hub for first-party images.
|
Push to `git.farh.net/cartsnitch/<service>` only. Never Docker Hub for first-party images.
|
||||||
|
|
||||||
## Task decomposition (for delegators)
|
## Task decomposition (for delegators)
|
||||||
|
|
||||||
|
|||||||
+22
-22
@@ -63,14 +63,14 @@ Gitea branch protection requires CI checks (lint, test, build-and-push). Governa
|
|||||||
## PR review & merge policy
|
## PR review & merge policy
|
||||||
|
|
||||||
### Dev branch (`dev`)
|
### Dev branch (`dev`)
|
||||||
- **QA** (Checkout Charlie) reviews the PR. Approve → hand to CTO. Fail → back to engineer directly with exact details.
|
- **QA** (Checkout Charlie `9b6012d0-0406-417e-bb22-78266a6e7f77`) reviews the PR. Approve → hand to CTO. Fail → back to engineer directly with exact details.
|
||||||
- **CTO** (Savannah Savings) reviews. Approve → CTO merges the `dev` PR. Fail → back to engineer.
|
- **CTO** (Savannah Savings `6ec1a5a9-113c-430b-90e6-260d60d79e1d`) reviews. Approve → CTO merges the `dev` PR. Fail → back to engineer.
|
||||||
|
|
||||||
### UAT branch (`uat`)
|
### UAT branch (`uat`)
|
||||||
- **CTO** opens and merges a `dev` → `uat` PR (single approval).
|
- **CTO** opens and merges a `dev` → `uat` PR (single approval).
|
||||||
|
|
||||||
### Main branch (`main`)
|
### Main branch (`main`)
|
||||||
- **CEO** (Coupon Carl) reviews and merges the `uat` → `main` PR.
|
- **CEO** (Coupon Carl `cd91facf-8f4c-4cbd-b8d8-b48da5b50727`) reviews and merges the `uat` → `main` PR.
|
||||||
|
|
||||||
`@cpfarhood` is cc'd for visibility on all PRs — never as a reviewer.
|
`@cpfarhood` is cc'd for visibility on all PRs — never as a reviewer.
|
||||||
|
|
||||||
@@ -79,7 +79,7 @@ Gitea branch protection requires CI checks (lint, test, build-and-push). Governa
|
|||||||
### Product analysis (feature intake)
|
### Product analysis (feature intake)
|
||||||
|
|
||||||
* Feature requests arrive at the CEO via Paperclip or Gitea Issues.
|
* Feature requests arrive at the CEO via Paperclip or Gitea Issues.
|
||||||
* CEO delegates to CMO (Markdown Martha) for review.
|
* CEO delegates to CMO (Markdown Martha `46614fb2-6d29-4ea3-bc46-4a3b94086e3c`) for review.
|
||||||
* CMO: Accepted → CEO routes to CTO for work breakdown. Backlogged → CEO handles prioritization. Denied → closed as unplanned.
|
* CMO: Accepted → CEO routes to CTO for work breakdown. Backlogged → CEO handles prioritization. Denied → closed as unplanned.
|
||||||
* CTO breaks accepted work into atomic tasks and assigns to Engineering.
|
* CTO breaks accepted work into atomic tasks and assigns to Engineering.
|
||||||
|
|
||||||
@@ -87,35 +87,35 @@ Gitea branch protection requires CI checks (lint, test, build-and-push). Governa
|
|||||||
|
|
||||||
1. **Engineer** branches from `dev`, writes code. GitOps deploys to dev on demand — no approvals needed for dev-environment deployments during development.
|
1. **Engineer** branches from `dev`, writes code. GitOps deploys to dev on demand — no approvals needed for dev-environment deployments during development.
|
||||||
2. **Engineer** opens a PR against `dev`. CI must pass.
|
2. **Engineer** opens a PR against `dev`. CI must pass.
|
||||||
3. **QA (Checkout Charlie)** reviews the PR. Fail → back to engineer.
|
3. **QA (Checkout Charlie `9b6012d0-0406-417e-bb22-78266a6e7f77`)** reviews the PR. Fail → back to engineer.
|
||||||
4. QA approves and hands off to CTO.
|
4. QA approves and hands off to CTO.
|
||||||
5. **CTO (Savannah Savings)** reviews the PR. Fail → back to engineer.
|
5. **CTO (Savannah Savings `6ec1a5a9-113c-430b-90e6-260d60d79e1d`)** reviews the PR. Fail → back to engineer.
|
||||||
6. **CTO** merges the dev PR.
|
6. **CTO** merges the dev PR.
|
||||||
7. **CI** builds and deploys automatically to Dev (`https://cartsnitch.dev.farh.net`).
|
7. **CI** builds and deploys automatically to Dev (`https://dev.cartsnitch.com`).
|
||||||
|
|
||||||
### Phase 2 — UAT promotion
|
### Phase 2 — UAT promotion
|
||||||
|
|
||||||
8. **CTO** opens and merges a PR from `dev` to `uat`.
|
8. **CTO** opens and merges a PR from `dev` to `uat`.
|
||||||
9. **CI** builds and deploys automatically to UAT (`https://cartsnitch.uat.farh.net`).
|
9. **CI** builds and deploys automatically to UAT (`https://uat.cartsnitch.com`).
|
||||||
10. **CTO** creates a UAT regression task for **Deal Dottie** immediately after promoting.
|
10. **CTO** creates a UAT regression task for **Deal Dottie (`161fb3bb-0332-4381-b67d-7c4b92a91133`)** immediately after promoting.
|
||||||
|
|
||||||
### Phase 3 — UAT testing & security
|
### Phase 3 — UAT testing & security
|
||||||
|
|
||||||
11. **UAT (Deal Dottie)** runs full regression against UAT — every feature, old and new, no exceptions.
|
11. **UAT (Deal Dottie `161fb3bb-0332-4381-b67d-7c4b92a91133`)** runs full regression against UAT — every feature, old and new, no exceptions.
|
||||||
12. UAT fail → CTO redistributes to engineer (return to Phase 1).
|
12. UAT fail → CTO redistributes to engineer (return to Phase 1).
|
||||||
13. UAT pass → **Security Engineer (Stockboy Steve)** performs a security code review of the changes.
|
13. UAT pass → **Security Engineer (Stockboy Steve `d59d4b24-3cc3-4616-a23a-2b4776a489ca`)** performs a security code review of the changes.
|
||||||
14. Security fail → CTO redistributes to engineer (return to Phase 1).
|
14. Security fail → CTO redistributes to engineer (return to Phase 1).
|
||||||
|
|
||||||
### Phase 4 — Production
|
### Phase 4 — Production
|
||||||
|
|
||||||
15. Security pass → **CEO (Coupon Carl)** reviews and merges the production PR (`uat → main`). Fail → back to CTO.
|
15. Security pass → **CEO (Coupon Carl `cd91facf-8f4c-4cbd-b8d8-b48da5b50727`)** reviews and merges the production PR (`uat → main`). Fail → back to CTO.
|
||||||
16. **CI** deploys automatically to Production (`https://cartsnitch.farh.net`).
|
16. **CI** deploys automatically to Production (`https://cartsnitch.com`).
|
||||||
|
|
||||||
### Hierarchy rules
|
### Hierarchy rules
|
||||||
|
|
||||||
* CTO rejections at Dev go directly to the engineer (not back through QA).
|
* CTO rejections at Dev go directly to the engineer (not back through QA).
|
||||||
* UAT failures (Deal Dottie) go to CTO — CTO cascades to engineer.
|
* UAT failures (Deal Dottie `161fb3bb-0332-4381-b67d-7c4b92a91133`) go to CTO — CTO cascades to engineer.
|
||||||
* Security failures (Stockboy Steve) go to CTO — CTO cascades to engineer.
|
* Security failures (Stockboy Steve `d59d4b24-3cc3-4616-a23a-2b4776a489ca`) go to CTO — CTO cascades to engineer.
|
||||||
* CEO rejections at Prod go to CTO.
|
* CEO rejections at Prod go to CTO.
|
||||||
|
|
||||||
> **Note on penetration testing:** Stockboy Steve performs scheduled penetration testing against Prod independently of the PR workflow. Board-authorized. Not triggered per-PR.
|
> **Note on penetration testing:** Stockboy Steve performs scheduled penetration testing against Prod independently of the PR workflow. Board-authorized. Not triggered per-PR.
|
||||||
@@ -156,12 +156,12 @@ Without this release, the receiving agent cannot check out the issue.
|
|||||||
|
|
||||||
## Infrastructure
|
## Infrastructure
|
||||||
|
|
||||||
* **Production:** namespace `cartsnitch`, FQDN `cartsnitch.farh.net`
|
* **Production:** namespace `cartsnitch`, FQDN `cartsnitch.com`
|
||||||
* **UAT:** namespace `cartsnitch-uat`, FQDN `cartsnitch.uat.farh.net`
|
* **UAT:** namespace `cartsnitch-uat`, FQDN `uat.cartsnitch.com`
|
||||||
* **Dev:** namespace `cartsnitch-dev`, FQDN `cartsnitch.dev.farh.net`
|
* **Dev:** namespace `cartsnitch-dev`, FQDN `dev.cartsnitch.com`
|
||||||
* **Cluster:** Kubernetes — cluster-wide read; read/write on `cartsnitch-dev` and `cartsnitch-uat`; read-only on `cartsnitch` (production).
|
* **Cluster:** Kubernetes — cluster-wide read; read/write on `cartsnitch-dev` and `cartsnitch-uat`; read-only on `cartsnitch` (production).
|
||||||
* **Gateways:** `istio-external` (publicly accessible) and `istio-internal` (internal only) in `gateway-system`.
|
* **Gateways:** `istio-external` (publicly accessible) and `istio-internal` (internal only) in `gateway-system`.
|
||||||
* **Container registry:** `ghcr.io/cartsnitch/<service>` only.
|
* **Container registry:** `git.farh.net/cartsnitch/<service>` only.
|
||||||
|
|
||||||
## Authentication
|
## Authentication
|
||||||
|
|
||||||
@@ -175,7 +175,7 @@ Without this release, the receiving agent cannot check out the issue.
|
|||||||
**Stage 1 — CI (runs in each application repo):**
|
**Stage 1 — CI (runs in each application repo):**
|
||||||
- Triggered automatically on every merge to `main`
|
- Triggered automatically on every merge to `main`
|
||||||
- Builds and tags the Docker image: CalVer (`YYYY.MM.DD[.N]`), `latest`, and `sha-<hash>`
|
- Builds and tags the Docker image: CalVer (`YYYY.MM.DD[.N]`), `latest`, and `sha-<hash>`
|
||||||
- Pushes tagged images to `ghcr.io/cartsnitch/<service>`
|
- Pushes tagged images to `git.farh.net/cartsnitch/<service>`
|
||||||
- Creates a CalVer git tag in the source repo
|
- Creates a CalVer git tag in the source repo
|
||||||
|
|
||||||
**Stage 2 — GitOps (Flux, managed externally):**
|
**Stage 2 — GitOps (Flux, managed externally):**
|
||||||
@@ -210,8 +210,8 @@ These are the only acceptable choices — alternatives are policy violations:
|
|||||||
* **Cache / pub-sub:** DragonflyDB Operator — no Redis.
|
* **Cache / pub-sub:** DragonflyDB Operator — no Redis.
|
||||||
* **Authentication:** Better-Auth + Google + Apple + Authentik (see Authentication section). Never build custom auth.
|
* **Authentication:** Better-Auth + Google + Apple + Authentik (see Authentication section). Never build custom auth.
|
||||||
* **Dependency updates:** Mend Renovate. **Dependabot is not used and will not be used.** Do not configure it.
|
* **Dependency updates:** Mend Renovate. **Dependabot is not used and will not be used.** Do not configure it.
|
||||||
* **Container registry:** `ghcr.io/cartsnitch/<service>` — no Docker Hub for first-party images.
|
* **Container registry:** `git.farh.net/cartsnitch/<service>` — no Docker Hub for first-party images.
|
||||||
* **Browser automation:** the `playwright` MCP server (`http://playwright:8931/mcp`). Never run Playwright locally or install browser binaries. Target dev (`cartsnitch.dev.farh.net`) — never test production.
|
* **Browser automation:** the `playwright` MCP server (`http://playwright:8931/mcp`). Never run Playwright locally or install browser binaries. Target dev (`dev.cartsnitch.com`) — never test production.
|
||||||
|
|
||||||
If a task requires deviating from any of the above, treat it as a destructive action: stop, file an issue with rationale, request board approval.
|
If a task requires deviating from any of the above, treat it as a destructive action: stop, file an issue with rationale, request board approval.
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user