# Platform Service-Level CI/CD Operating Model v1

Status: active operating model
Owner: Release Engineering / Platform Governance
Last updated: 2026-06-03
Fairway task: `PSSM-PROD-C11-SERVICE-LEVEL-CICD-OPERATING-MODE-001`

## Purpose

Define the CI/CD model that becomes useful after Platform Shared Services Model
maturity. The goal is not immediate microservice extraction. The goal is to let
the monorepo validate changes by ownership while preserving global contract and
cross-domain safety.

Target model:

```text
contract-global + domain-local + consumer-smoke + service-evidence
```

## Gate Layers

| Layer | Question answered | Examples |
|---|---|---|
| Global contract gates | Does the whole platform contract still hold? | OpenAPI/AsyncAPI, codegen drift, schema compatibility, security baseline, boundary guards |
| Domain-local gates | Is the owning domain internally correct? | package tests, worker tests, migrations, local policy/evidence checks |
| Consumer smokes | Did the domains that consume this contract still work? | GPUaaS -> billing, App Platform -> artifacts/evidence, product -> IAM/authz |
| Service evidence bundles | Is this domain ready to promote independently or claim maturity? | release profile gates, degradation evidence, rollback, smoke, SLO, guard report |

Global gates remain mandatory. Domain-local gates reduce feedback time; they do
not hide cross-domain regressions.

## Ownership Inputs

Selective routing must be generated from owned maps, not ad hoc path globs:

| Input | Use |
|---|---|
| `ownership-maps/package-ownership.md` | package test and review owner routing |
| `ownership-maps/route-ownership.md` | API/handler smoke and route-placement guard routing |
| `ownership-maps/schema-ownership.md` | migration/schema drift and DB integration test routing |
| `ownership-maps/event-ownership.md` | AsyncAPI/event/outbox/DLQ test routing |
| `ownership-maps/worker-binary-ownership.md` | worker build, smoke, and deploy routing |
| `ownership-maps/frontend-surface-ownership.md` | frontend page-family test and review routing |
| `guard-fingerprint-baseline.tsv` and `guard-allowed-debt.tsv` | new-versus-legacy guard enforcement |
| `.fairway/artifacts/platform-shared-services-extraction-packets.yaml` | independent promotion eligibility |

If a file cannot be mapped to an owner, the change must run broad global gates
and require architecture review.

## Domain Lane Shape

Each domain lane should declare:

```yaml
domain_lane:
  domain_id: platform-billing
  source_paths:
    - packages/platform/billing/**
    - cmd/billing-worker/**
    - doc/api/**billing**
    - doc/architecture/**Billing**
  global_gates:
    - contracts
    - codegen
    - boundary_guard
    - security_baseline
  domain_local_gates:
    - go test ./packages/platform/billing ./cmd/billing-worker
    - migration/schema drift checks for billing-owned tables
    - ledger invariant tests
  consumer_smokes:
    - GPUaaS launch billing precheck
    - App runtime usage attribution
  service_evidence:
    - release profile evidence
    - degradation harness
    - reconciliation evidence
    - rollback posture
```

## Independent Promotion Eligibility

A domain can move toward independent promotion only when every item below is
true:

1. keep/split/extract decision packet exists and recommends `split_worker` or
   `extract_service`;
2. service-auth packet exists for every cross-process caller;
3. degradation contract has an executable smoke or harness;
4. rollback command is tested and documented;
5. release profile gates pass in enforcing mode for the domain;
6. consumer smokes pass for every supported product consumer;
7. Status/Ops has a component row and SLO evidence for the domain;
8. boundary guards are clean in `blocking_new` for new findings.

Without those, the domain may still have selective CI, but it cannot promote
independently from the platform-control release unit.

## Default Domain Groups

| Domain group | Typical paths | Required consumer smokes |
|---|---|---|
| Platform IAM/Auth | `packages/platform/iam`, `packages/platform/auth`, auth routes | user login/authz, service-account scope validation, product route denial |
| Platform Billing/Metering | `packages/platform/billing`, `cmd/billing-worker` | GPUaaS billing precheck, app runtime attribution, ledger invariant |
| Platform Evidence/Status | `packages/platform/evidence`, `packages/platform/statusops` | release evidence payload, status readiness, public status |
| Platform Registry/Artifacts | `packages/platform/registry`, `packages/platform/artifacts` | registry runtime verification, artifact trust/promotion |
| Platform Policy/Quota | `packages/platform/policy`, quota/config routes | access quota posture, launch/app/token denial reason |
| Platform Secrets/PKI | `packages/platform/secrets`, `packages/shared/pki` | rotation/expiry evidence, service-auth credential delivery |
| GPUaaS product | `packages/products/gpuaas`, provisioning/node/terminal binaries | allocation lifecycle, node-agent task, terminal route |
| App Platform product | `packages/products/appplatform`, app runtime/proxy workers | manifest validation, launch/connect/decommission smoke |
| Frontend surfaces | `packages/web` and page-family routes | focused page-family tests plus global navigation/typecheck |

## Gate Routing Rules

| Change class | Minimum route |
|---|---|
| Contract/API/event change | global contract gates, codegen, affected domain-local tests, all listed consumer smokes |
| Schema/seed change | schema drift guard, migration validation, affected domain tests, API/read-model smoke |
| Platform shared-service package change | global boundary guard, domain-local tests, consumer smokes, service evidence if production-impacting |
| Product package change | product-local tests, affected shared-service consumer smokes, UAT evidence if user/runtime flow changes |
| Frontend page-family change | frontend focused tests, source docs/UX gate, affected API smoke when data contract changes |
| CI/CD/profile change | release profile resolver, preflight smoke, evidence gate, dry-run or validation-only profile |
| Docs-only architecture change | source-doc validation, portal build, Fairway evidence; no deploy unless generated portal artifacts ship |

## Fast Profiles And Gate Skips

Fast profiles may skip expensive lanes only when they reference prior evidence
for the same source SHA or immutable artifact digest.

Required fast-profile evidence:

1. source SHA or manifest digest validated by global gates;
2. skipped gate list with reason;
3. profile-specific smoke;
4. rollback posture;
5. owner approval when residual risk remains.

Fast profiles must not become a way to ship unvalidated source or stale
generated artifacts.

## Fairway Integration

Fairway should track the execution state:

| Fairway item | Required use |
|---|---|
| Epic | one domain or release-profile migration |
| Task | one owned gate, smoke, packet, or implementation slice |
| Evidence | exact command, result, artifact, source SHA, and profile |
| Handoff | consumer-smoke owner or reviewer transfer |
| Review | architecture/security/governance approval for exceptions |

The dashboard should make skipped, partial, blocked, and not-applicable gates
visible. Hidden skips are release debt.

## Related Docs

- `doc/architecture/platform-foundation/Platform_Shared_Services_Completion_Roadmap_v1.md`
- `doc/architecture/platform-foundation/Platform_Release_Profile_Gates_v1.md`
- `doc/architecture/platform-foundation/Platform_Deployment_Extraction_Readiness_v1.md`
- `doc/architecture/platform-foundation/Platform_Foundation_Guard_Graduation_Plan_v1.md`
- `doc/architecture/platform-foundation/ownership-maps/README.md`
- `doc/governance/Platform_Control_Release_Promotion_Policy.md`
