Files
org/skills/sdlc/SKILL.md
T
Chris Farhood 53bc4132ca refactor(sdlc): simplify — remove handoff protocol and self-merge section
Align with groombook SDLC style: engineer self-merges dev, QA merges uat,
CEO merges main. Drop the explicit 3-step handoff protocol (Paperclip
handles it via in_review). Remove the redundant "no self-merge" footer.
Keep delegation model tier, board approval gate, and cc @cpfarhood.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-24 15:42:58 -04:00

9.4 KiB

name, description
name description
sdlc Software development lifecycle for CartSnitch. Covers Gitea authentication, branch strategy across Dev/UAT/Prod, the SDLC pipeline phases, PR review and merge policy, 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 Gitea 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 Engineer (self-merges after CI passes)
uat UAT QA (merges after code review)
main Production CEO (merges after UAT validation)

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 Paperclip — Gitea-native review approvals are not required because all agents share the Gitea App identity.

PR review & merge policy

Dev branch (dev)

  • Engineer self-merges after CI passes. Dev is for validation, not quality gates.
  • QA (Checkout Charlie 9b6012d0-0406-417e-bb22-78266a6e7f77) reviews the PR. Fail → back to engineer with exact details.
  • QA approves and hands off to CTO.
  • CTO (Savannah Savings 6ec1a5a9-113c-430b-90e6-260d60d79e1d) reviews the PR. Fail → back to engineer.
  • CTO merges the dev PR.

UAT branch (uat)

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

Main branch (main)

  • CEO (Coupon Carl cd91facf-8f4c-4cbd-b8d8-b48da5b50727) reviews and merges the uat → main PR.
  • CI deploys automatically to Production (https://cartsnitch.com).

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

SDLC pipeline

Phase 1 — Dev

  1. Engineer branches from dev, writes code. GitOps deploys to dev on demand.
  2. Engineer opens a PR against dev. CI must pass.
  3. Engineer self-merges after CI passes.
  4. CI builds and deploys automatically to Dev (https://dev.cartsnitch.com).
  5. QA (Checkout Charlie) reviews the PR. Fail → back to engineer.
  6. QA approves and hands off to CTO.
  7. CTO (Savannah Savings) reviews the PR. Fail → back to engineer.
  8. CTO merges the dev PR.

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).

Phase 3 — UAT testing & security

  1. UAT (Deal Dottie) 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) 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) go to CTO — CTO cascades to engineer.
  • Security failures (Stockboy Steve) 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.

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 (public) and istio-internal (internal) 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:

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.

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). Target dev only — 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.