Files
org/skills/sdlc/SKILL.md
T
Chris Farhood 4b17a4619d 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>
2026-05-23 15:19:04 -04:00

11 KiB

name, description
name description
sdlc Software development lifecycle for CartSnitch. Covers Gitea authentication, branch strategy across Dev/UAT/Prod, the four-phase SDLC pipeline with product analysis intake, PR review and merge policy, the handoff protocol, status semantics, infrastructure layout, the Gitea-origin issue board-approval gate, the cc-cpfarhood visibility rule, and delegation model tier policy.

Software Development Lifecycle

Gitea authentication

Use the GITEA_TOKEN environment variable for all Gitea operations. It is already set in the agent environment. Use the tea CLI for all Gitea/Git operations (e.g., tea issue list, tea pr create). The token expires when the environment variable is rotated — re-invoke any Gitea operation if you get a 401.

Gitea is the primary source of truth. Every Paperclip issue must have a corresponding Gitea issue (create one if missing). Both stay open until the work is completed, reviewed, approved, merged, and QA-verified.

Gitea-origin issue policy — board approval required

If a task originated from Gitea (originKind: "gitea"), do not begin work. Immediately create a board approval:

POST /api/companies/{companyId}/approvals
{
  "type": "request_board_approval",
  "requestedByAgentId": "{your-agent-id}",
  "issueIds": ["{issueId}"],
  "payload": {
    "title": "Board approval required: Gitea issue",
    "summary": "Summarize what the GitHub issue requests.",
    "recommendedAction": "Approve to begin work.",
    "risks": ["Work begins without board review if approved."]
  }
}

Set the issue to blocked with a comment linking to the approval. Only proceed once PAPERCLIP_APPROVAL_ID is set and PAPERCLIP_APPROVAL_STATUS indicates approval.

Branch strategy

Three long-lived branches map to the three deployment environments:

Branch Environment Who merges
dev Dev CTO (after QA approval)
uat UAT CTO (promotes devuat)
main Production CEO (promotes uatmain)

Engineers always target dev — never uat or main directly. Feature branches: <agent-name>/<short-description>.

Pull requests

All changes happen via pull request. Always include cc @cpfarhood at the bottom of the PR body for visibility — never as a reviewer.

tea pr create --base dev --title "..." --body "... cc @cpfarhood"

Gitea branch protection requires CI checks (lint, test, build-and-push). Governance is enforced through the Paperclip SDLC — Gitea-native review approvals are not required because all agents share the Gitea App identity. Paperclip approval tracking is the authoritative record.

PR review & merge policy

Dev branch (dev)

  • 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 6ec1a5a9-113c-430b-90e6-260d60d79e1d) reviews. Approve → CTO merges the dev PR. Fail → back to engineer.

UAT branch (uat)

  • CTO opens and merges a devuat PR (single approval).

Main branch (main)

  • CEO (Coupon Carl cd91facf-8f4c-4cbd-b8d8-b48da5b50727) reviews and merges the uatmain PR.

@cpfarhood is cc'd for visibility on all PRs — never as a reviewer.

SDLC pipeline

Product analysis (feature intake)

  • Feature requests arrive at the CEO via Paperclip or Gitea Issues.
  • 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.
  • CTO breaks accepted work into atomic tasks and assigns to Engineering.

Phase 1 — Dev

  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.
  3. QA (Checkout Charlie 9b6012d0-0406-417e-bb22-78266a6e7f77) reviews the PR. Fail → back to engineer.
  4. QA approves and hands off to CTO.
  5. CTO (Savannah Savings 6ec1a5a9-113c-430b-90e6-260d60d79e1d) reviews the PR. Fail → back to engineer.
  6. CTO merges the dev PR.
  7. CI builds and deploys automatically to Dev (https://dev.cartsnitch.com).

Phase 2 — UAT promotion

  1. CTO opens and merges a PR from dev to uat.
  2. CI builds and deploys automatically to UAT (https://uat.cartsnitch.com).
  3. CTO creates a UAT regression task for Deal Dottie (161fb3bb-0332-4381-b67d-7c4b92a91133) immediately after promoting.

Phase 3 — UAT testing & security

  1. UAT (Deal Dottie 161fb3bb-0332-4381-b67d-7c4b92a91133) runs full regression against UAT — every feature, old and new, no exceptions.
  2. UAT fail → CTO redistributes to engineer (return to Phase 1).
  3. UAT pass → Security Engineer (Stockboy Steve d59d4b24-3cc3-4616-a23a-2b4776a489ca) performs a security code review of the changes.
  4. Security fail → CTO redistributes to engineer (return to Phase 1).

Phase 4 — Production

  1. Security pass → CEO (Coupon Carl cd91facf-8f4c-4cbd-b8d8-b48da5b50727) reviews and merges the production PR (uat → main). Fail → back to CTO.
  2. CI deploys automatically to Production (https://cartsnitch.com).

Hierarchy rules

  • CTO rejections at Dev go directly to the engineer (not back through QA).
  • UAT failures (Deal Dottie 161fb3bb-0332-4381-b67d-7c4b92a91133) 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.

Note on penetration testing: Stockboy Steve performs scheduled penetration testing against Prod independently of the PR workflow. Board-authorized. Not triggered per-PR.

Delegation model tier

When creating subtasks for other agents, set modelProfile: "cheap" only for:

  • Mechanical refactors or repetitive operations
  • Basic information lookups
  • Well-specified, bounded updates

Leave modelProfile unset for anything requiring judgment, reasoning, or QA review.

When in doubt, leave it unset.

Handoff protocol — mandatory

Every handoff to another agent requires ALL THREE steps:

1. Explicit assignment

PATCH /api/issues/{id} with assigneeAgentId: "<target-agent-uuid>". Mentioning is NOT a handoff — the agent won't wake without explicit assignment.

2. Status = todo

Every handoff sets status: "todo". Never in_review, never backlog — both are invisible in inbox-lite and the receiver won't wake.

3. Release checkout

POST /api/issues/{issueId}/release
Headers: Authorization: Bearer $PAPERCLIP_API_KEY, X-Paperclip-Run-Id: $PAPERCLIP_RUN_ID

Without this release, the receiving agent cannot check out the issue.

Saying you are reassigning a task is NOT the same as reassigning it. Verify the PATCH succeeded (200) before posting a comment claiming the handoff is done.

Infrastructure

  • Production: namespace cartsnitch, FQDN cartsnitch.com
  • UAT: namespace cartsnitch-uat, FQDN uat.cartsnitch.com
  • 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).
  • Gateways: istio-external (publicly accessible) and istio-internal (internal only) in gateway-system.
  • Container registry: git.farh.net/cartsnitch/<service> only.

Authentication

  • Framework: Better-Auth.
  • Social login: Google and Apple OAuth.
  • SSO: Authentik OIDC at https://auth.farh.net (credentials in authentik-credentials secret).
  • Never build custom authentication.

Deployment — 2-stage Flux GitOps

Stage 1 — CI (runs in each application repo):

  • Triggered automatically on every merge to main
  • Builds and tags the Docker image: CalVer (YYYY.MM.DD[.N]), latest, and sha-<hash>
  • Pushes tagged images to git.farh.net/cartsnitch/<service>
  • Creates a CalVer git tag in the source repo

Stage 2 — GitOps (Flux, managed externally):

  • Flux watches cartsnitch/infra as the target GitRepository — it is not a Flux bootstrap/cluster repo and must never be treated as one.
  • Reconciles Kustomize overlays: apps/overlays/devcartsnitch-dev, apps/overlays/uatcartsnitch-uat, apps/overlays/prodcartsnitch.
  • Images currently use :latest with imagePullPolicy: Always; pin to a CalVer tag in the infra overlay when stabilizing a release.

Policy — Flux Image Tag Automation is DENIED. Do NOT use ImageRepository, ImagePolicy, or ImageUpdateAutomation Flux resources. Image tag updates must be made intentionally via a PR to cartsnitch/infra.

To deploy a change:

  1. Merge code to main in the app repo — CI builds and pushes a new image automatically.
  2. Open a PR against cartsnitch/infra to update the relevant overlay; merge after kustomize CI passes.
  3. Flux reconciles cartsnitch/infra on merge and rolls out the updated pods.

To force a rollout without a manifest change (e.g., pick up a new :latest on stuck nodes):

kubectl rollout restart deployment/<name> -n <namespace>

Infrastructure as Code

Terraform (OpenTofu) is deployed via the Flux OpenTofu Controller in a GitOps fashion. Submit Terraform configurations via a PR to cartsnitch/infra — the tofu controller reconciles them on merge. Use for Authentik configuration, DNS, or other infra provisioning.

Never run tofu directly. Never kubectl apply against production. Production changes go through Flux only. The cartsnitch-dev and cartsnitch-uat namespaces permit direct kubectl use for iteration.

Tools (canonical, not alternatives)

These are the only acceptable choices — alternatives are policy violations:

  • Secret management: Bitnami Sealed Secrets Controller — no plain Kubernetes secrets.
  • Database: CloudNativePG Operator (Postgres) — no SQLite, MariaDB, or MySQL.
  • Cache / pub-sub: DragonflyDB Operator — no Redis.
  • 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.
  • 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 (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.

External communication

When communicating in any context visible outside the CartSnitch agent team (external users, human reviewers, non-agent entities), include cc @cpfarhood for visibility — never as a reviewer.

No self-merge

No agent merges their own PR. The merger is always the next role up the SDLC ladder (CTO for dev and uat, CEO for main).