Project Minimum Requirements
1. Purpose
This document defines the minimum bar for onboarding any project into the GE CI/CD pipeline. A project that does not meet these requirements CANNOT proceed from development to production.
Audience:
- PM agents (primary) — read this to generate gap analysis and work packages
- Development teams — use this as a checklist before first commit
- Human PMs — append this to every project onboarding plan
Goal: Every project produces a ge-ci.yaml manifest and meets every requirement for its declared stack, so the pipeline runs green from first commit through production deployment.
This document tells you WHAT must exist. Methodology docs tell you HOW.
Normative References
| Document |
Location |
Governs |
| GE Constitution v2 |
config/constitution.md |
10 binding principles |
| Codebase Standards |
CODEBASE-STANDARDS.md |
Directory law, file hygiene, strict types |
| TDD Methodology |
ge-ops/wiki/docs/methodologies/tdd/ |
Spec-first workflow |
| Anti-LLM Pipeline |
ge-ops/wiki/docs/methodologies/anti-llm-pipeline/ |
10-stage quality system |
| Security-First |
ge-ops/wiki/docs/methodologies/security-first/ |
Threat modeling, OWASP |
| API-First Design |
ge-ops/wiki/docs/methodologies/api-first/ |
OpenAPI contract |
| Testing Standards |
ge-ops/wiki/docs/development/standards/testing.md |
Proof of life, integration tests |
| Naming Conventions |
ge-ops/wiki/docs/development/standards/naming.md |
kebab-case, PascalCase, etc. |
2. How the GE CI/CD Pipeline Works
Pipeline Generation
- Project declares
ge-ci.yaml at repo root
python3 config/ci/generate-pipeline.py reads the manifest, resolves checks, and writes .gitlab-ci.yml
- The generated file is committed — never hand-edited
The 3 Tiers
| Tier |
Triggers On |
Target |
Purpose |
| FAST |
Every push, every MR |
< 2 min |
Immediate feedback: lint, unit tests, TDD gates, SSOT |
| STANDARD |
MR + main push + schedule + API |
< 5 min |
Security SAST, integration tests, property tests, policy, merge-gate |
| FULL |
Nightly schedule + manual + API |
< 15 min |
Mutation testing, e2e, adversarial/fuzz — the heavy lifting |
Deploy stages (deploy:staging, security:dast, deploy:production) trigger on main/develop branches and API.
The 18 Pipeline Stages
lint — 2. knowledge — 3. build — 4. test:unit — 5. test:tdd-gates — 6. security:sast — 7. test:integration — 8. test:mutation — 9. test:adversarial — 10. test:property — 11. verify:ssot — 12. test:reconciliation — 13. test:contract — 14. verify:policy — 15. review — 16. deploy:staging — 17. security:dast — 18. deploy:production
6 Mandatory Checks (cannot be disabled)
secrets, oracle-check, ssot, brain-feed, policy, merge-gate
In ge-ci.yaml:
checks:
extra:
- iac-checkov # Kubernetes manifest scanning
- iac-kubesec # Kubernetes security scoring
- contract # OpenAPI spec drift detection
- license # License compliance (AGPL/SSPL blocking)
- dast-zap # OWASP ZAP dynamic scanning
- dast-nuclei # Nuclei template scanning
disabled: [] # Cannot include mandatory checks
3. Project Manifest (ge-ci.yaml)
Minimal Example (Python API)
schema_version: "1.0"
project:
name: "my-service"
team: "alfa" # alfa, bravo, zulu, or shared
type: "service" # service, internal, client
stack:
languages:
- python:
packages: ["my_service"]
pyright_targets: "my_service/api.py my_service/models.py"
modules:
- "my_service.api:create_app"
test_paths:
unit: ["tests/unit/"]
integration: ["tests/integration/"]
tdd: ["tests/tdd/"]
property: ["tests/property/"]
Full Example (Fullstack with Deploy)
schema_version: "1.0"
project:
name: "my-project"
team: "alfa"
type: "client"
stack:
languages:
- python:
packages: ["my_backend"]
pyright_targets: "my_backend/api.py"
modules:
- "my_backend.api:create_app"
test_paths:
unit: ["tests/unit/"]
integration: ["tests/integration/"]
tdd: ["tests/tdd/"]
property: ["tests/property/"]
- typescript:
root: "frontend"
test_paths:
unit: [] # Vitest auto-discovers
integration: ["tests/integration/"]
e2e: ["tests/e2e/"]
property: ["tests/property/"]
vitest_exclude: "tests/integration/**,tests/e2e/**"
container:
dockerfile: "Dockerfile"
build_context: "."
deploy:
argocd:
apps: ["my-project"]
staging_url: "http://my-project.ge-system.svc.cluster.local"
health_url: "http://192.168.1.85/api/health"
smoke_url: "http://192.168.1.85"
smoke_host: "my-project.ge.internal"
checks:
extra:
- iac-checkov
- contract
- license
- dast-zap
- dast-nuclei
disabled: []
variables:
TDD_MUTATION_THRESHOLD: "80"
TDD_COVERAGE_THRESHOLD: "85"
Generating the Pipeline
python3 config/ci/generate-pipeline.py --validate # Check manifest only
python3 config/ci/generate-pipeline.py --dry-run # Preview to stdout
python3 config/ci/generate-pipeline.py # Write .gitlab-ci.yml
4. Minimum Requirements Per Stage
FAST Tier — MUST have from first commit
Stage: lint
| Check |
Stack |
Tool |
Project MUST provide |
lint:python |
Python |
ruff |
ruff.toml or pyproject.toml with [tool.ruff] section |
lint:deadcode |
Python |
vulture |
Optional: vulture_whitelist.py for known false positives |
types:python |
Python |
pyright |
Type hints on all function signatures; files listed in pyright_targets |
lint:secrets |
All |
gitleaks |
.gitleaks.toml config file; .gitleaks-baseline.json for known false positives |
test:unit:frontend (lint portion) |
TypeScript |
eslint + tsc |
ESLint config (.eslintrc.* or eslint.config.*); tsconfig.json with strict: true |
Stage: knowledge
| Check |
Stack |
Tool |
Project MUST provide |
knowledge:brain-feed |
All |
brain_feed.py |
No project config needed — runs automatically on every commit |
Stage: build
| Check |
Stack |
Tool |
Project MUST provide |
build:backend |
Python |
python3 import |
All modules in GE_PYTHON_MODULES MUST be importable; all deps in requirements.txt |
Stage: test:unit
| Check |
Stack |
Tool |
Project MUST provide |
test:unit:backend |
Python |
pytest |
Test files in test_paths.unit directories; pytest-xdist and pytest-cov in deps; tests pass with -n auto |
test:unit:frontend (test portion) |
TypeScript |
vitest |
vitest.config.ts; test files auto-discovered; @vitest/coverage-v8 in devDependencies |
Stage: test:tdd-gates
| Check |
Stack |
Tool |
Project MUST provide |
tdd:oracle-check |
Python |
AST analysis |
If tests/tdd/ exists: each test imports from at most ONE implementation package; no eval/exec/compile calls |
Stage: verify:ssot
| Check |
Stack |
Tool |
Project MUST provide |
verify:ssot |
All |
Python scan |
Zero hardcoded absolute paths in production code or config YAML; openapi.yaml recommended |
STANDARD Tier — MUST have before first MR
Stage: security:sast
| Check |
Stack |
Tool |
Project MUST provide |
security:bandit |
Python |
bandit |
Python source in declared packages; zero CRITICAL (HIGH severity + HIGH confidence) findings |
security:semgrep |
All |
semgrep |
Optional: config/semgrep-rules/ for custom rules; --config=auto runs community rules |
security:dependency-scan |
Python |
safety + trivy |
requirements.txt; zero CRITICAL Trivy findings |
security:npm-audit |
TypeScript |
npm audit |
package-lock.json; zero critical npm vulnerabilities |
security:iac-checkov |
K8s (opt-in) |
checkov |
k8s/ directory with Kubernetes manifests; zero HIGH severity findings |
security:iac-kubesec |
K8s (opt-in) |
kubesec |
All containers MUST have securityContext; no privileged: true (except Falco) |
security:license-scan |
Python (opt-in) |
pip-licenses |
Zero AGPL/SSPL dependencies |
Stage: test:integration
| Check |
Stack |
Tool |
Project MUST provide |
test:integration |
Python |
pytest |
Tests at test_paths.integration; tests MUST work with postgres:15 and redis:7 service containers |
Stage: test:adversarial
| Check |
Stack |
Tool |
Project MUST provide |
test:adversarial |
Python |
AST + Hypothesis |
tests/property/ or tests/adversarial/ directory with pytest-compatible tests |
Stage: test:property
| Check |
Stack |
Tool |
Project MUST provide |
test:property:python |
Python |
Hypothesis |
Property-based tests using hypothesis with @given decorators |
test:property:typescript |
TypeScript |
fast-check |
Property-based tests in tests/property/ under TS root; fast-check in devDependencies |
Stage: test:reconciliation
| Check |
Stack |
Tool |
Project MUST provide |
test:reconciliation |
Python |
reconcile_tests.py |
tests/tdd/ with TDD specs; tests/unit/ with corresponding unit test coverage |
Stage: test:contract (opt-in)
| Check |
Stack |
Tool |
Project MUST provide |
test:contract |
API projects |
generate-openapi.py |
openapi.yaml at repo root; scripts/generate-openapi.py regenerates spec from route files; all operations MUST have operationId |
Stage: verify:policy
| Check |
Stack |
Tool |
Project MUST provide |
verify:policy |
All |
OPA conftest |
config/ci/policies/ directory with at least 1 .rego policy file |
Stage: review
| Check |
Stack |
Tool |
Project MUST provide |
merge:gate |
All |
Python scoring |
No new artifacts required — reads JUnit XML, SAST reports, dependency scans from prior stages. Threshold: 70/100 score. Generates SOC 2 CC8.1 compliance evidence |
FULL Tier — MUST have before first release
Stage: test:mutation
| Check |
Stack |
Tool |
Project MUST provide |
test:mutation |
Python |
mutmut |
setup.cfg with [mutmut] section: paths_to_mutate, tests_dir, runner; score MUST meet TDD_MUTATION_THRESHOLD (default: 80%) |
mutation:typescript |
TypeScript |
Stryker |
stryker.config.mjs in TS root; @stryker-mutator/core in devDependencies; incremental mode enabled |
Stage: test:integration (TypeScript)
| Check |
Stack |
Tool |
Project MUST provide |
test:integration:frontend |
TypeScript |
vitest |
Integration tests in tests/integration/ under TS root; tests work with postgres:15 service container |
Stage: test:e2e
| Check |
Stack |
Tool |
Project MUST provide |
test:e2e |
TypeScript |
Playwright |
playwright.config.ts in TS root; tests in tests/e2e/; Chromium project configured; baseURL reads from PLAYWRIGHT_BASE_URL env |
Deploy — MUST have before first deployment
Stage: deploy:staging
| Check |
Stack |
Tool |
Project MUST provide |
build:image |
All |
Kaniko |
Dockerfile at path declared in container.dockerfile; multi-stage build recommended |
sign:image |
All |
Cosign + Syft |
No project config needed — runs against built image |
deploy:staging |
All |
ArgoCD API |
ArgoCD app names in deploy.argocd.apps; ARGOCD_AUTH_TOKEN in CI/CD variables |
verify:smoke |
TypeScript |
Playwright |
tests/e2e/smoke.spec.ts in TS root — lightweight tests verifying deployed app responds |
Stage: security:dast (opt-in)
| Check |
Stack |
Tool |
Project MUST provide |
security:dast-scan |
Web apps |
OWASP ZAP |
smoke_url and smoke_host configured in manifest; deployed staging app accessible |
security:dast-nuclei |
Web apps |
Nuclei |
Deployed staging app accessible via smoke_url |
Stage: deploy:production
| Check |
Stack |
Tool |
Project MUST provide |
deploy:production |
All |
ArgoCD |
Manual gate (human approval required); DAST report MUST exist; zero CRITICAL findings |
verify:health |
All |
HTTP GET |
Health endpoint at deploy.health_url returning HTTP 200 with JSON body |
5. Machine-Readable Checklist
PM agents: parse this YAML block to generate gap analysis. Compare each item against the project filesystem and ge-ci.yaml. Group gaps by tier priority: FAST (P0), STANDARD (P1), FULL (P2), DEPLOY (P3).
# GE Project Minimum Requirements Checklist v1.0
# Usage: PM agent reads this, scans project, emits work packages for gaps
checklist:
manifest:
- id: M1
item: "ge-ci.yaml exists at repo root"
required: true
- id: M2
item: "schema_version is '1.0'"
required: true
- id: M3
item: "project.name is set"
required: true
- id: M4
item: "project.team is set (alfa, bravo, zulu, or shared)"
required: true
- id: M5
item: "stack.languages declares at least one language"
required: true
fast_tier:
- id: F1
item: ".gitleaks.toml exists"
required: true
stage: lint
check: secrets
- id: F2
item: "Linter config exists (ruff.toml or pyproject.toml for Python; eslint config for TS)"
required: true
stage: lint
stack: per-language
- id: F3
item: "tsconfig.json with strict: true (TypeScript)"
required: true
stage: lint
stack: typescript
- id: F4
item: "Unit test directory exists and contains at least 1 test"
required: true
stage: test:unit
- id: F5
item: "vitest.config.ts exists (TypeScript)"
required: true
stage: test:unit
stack: typescript
- id: F6
item: "pytest-cov and pytest-xdist in requirements (Python)"
required: true
stage: test:unit
stack: python
- id: F7
item: "Type hints on all function signatures (Python)"
required: true
stage: lint
stack: python
- id: F8
item: "All GE_PYTHON_MODULES entries are importable"
required: true
stage: build
stack: python
- id: F9
item: "Zero hardcoded absolute paths in production code"
required: true
stage: verify:ssot
standard_tier:
- id: S1
item: "config/ci/policies/ directory with at least 1 .rego file"
required: true
stage: verify:policy
- id: S2
item: "Integration test directory with at least 1 test"
required: true
stage: test:integration
- id: S3
item: "Property-based tests exist (tests/property/ or tests/adversarial/)"
required: true
stage: test:adversarial
stack: python
- id: S4
item: "requirements.txt exists (Python dependency scanning)"
required: true
stage: security:sast
stack: python
- id: S5
item: "package-lock.json exists (npm audit)"
required: true
stage: security:sast
stack: typescript
- id: S6
item: "openapi.yaml with operationId on all operations (if contract check enabled)"
required: false
stage: test:contract
- id: S7
item: "Zero AGPL/SSPL dependencies (if license check enabled)"
required: false
stage: security:sast
full_tier:
- id: R1
item: "setup.cfg with [mutmut] section (Python mutation testing)"
required: true
stage: test:mutation
stack: python
- id: R2
item: "stryker.config.mjs exists (TypeScript mutation testing)"
required: true
stage: test:mutation
stack: typescript
- id: R3
item: "playwright.config.ts exists (E2E testing)"
required: true
stage: test:integration
stack: typescript
- id: R4
item: "tests/e2e/ directory with at least 1 test"
required: true
stage: test:integration
stack: typescript
deploy:
- id: D1
item: "Dockerfile exists at declared path"
required: true
stage: deploy:staging
- id: D2
item: "ArgoCD apps declared in deploy.argocd.apps"
required: true
stage: deploy:staging
- id: D3
item: "Health endpoint exists and returns HTTP 200 + JSON"
required: true
stage: deploy:production
- id: D4
item: "tests/e2e/smoke.spec.ts exists (smoke tests)"
required: true
stage: deploy:staging
stack: typescript
- id: D5
item: "smoke_url and smoke_host configured in manifest"
required: true
stage: deploy:staging
6. Quick Start
- Copy the minimal
ge-ci.yaml template from Section 3
- Declare your stack and test paths
- Run
python3 config/ci/generate-pipeline.py --validate to verify manifest
- Run
python3 config/ci/generate-pipeline.py --dry-run to preview pipeline
- Commit
ge-ci.yaml and generated .gitlab-ci.yml
- FAST tier first — these run on every push. Fix lint, unit tests, secrets, SSOT.
- STANDARD tier before first MR — add integration tests, property tests, policy files.
- FULL tier before first release — add mutation testing config, e2e tests, Playwright.
- DEPLOY tier before first deployment — Dockerfile, ArgoCD config, health endpoint, smoke tests.
A PM agent running gap analysis against this checklist will produce work packages in this exact priority order.