feature/pp-58-runtime-image-contract (#68)
## Summary This PR tightens repository quality enforcement around markdown and documentation. It adds `markdownlint` to the `cicd-checks` workflow, expands pre-commit coverage so markdown files are checked repo-wide, and cleans up the PP-58 documentation set to keep it aligned with the new policy. ## What changed - Added a `Markdownlint Check` entry to `.gitea/workflows/cicd-checks.yaml` - Added `markdownlint` to pre-commit and widened prettier coverage to include markdown files across the repo - Updated `README.md` to satisfy markdownlint line-length rules - Normalized the PP-58 documentation set: - `docs/DEPLOYABLE_RUNTIME_CONTRACT.md` - `docs/adr/ADR003-deployable_runtime_image_contract.md` - `docs/DEVELOPMENT.md` - `docs/CICD_MULTI_STAGE_BUILD.md` - `docs/CICD_TROUBLESHOOTING_GUIDE.md` - `docs/SECURE_DOCKER_CICD.md` ## Validation - `pre-commit run markdownlint --files README.md docs/DEPLOYABLE_RUNTIME_CONTRACT.md` - `pre-commit run prettier --files README.md docs/DEPLOYABLE_RUNTIME_CONTRACT.md` - Workflow YAML validation returned no errors ## Notes This change does not alter application runtime behavior. It only strengthens CI and documentation quality enforcement. Co-authored-by: copilotcoder <copilotcoder@darkhelm.org> Reviewed-on: #68
This commit was merged in pull request #68.
This commit is contained in:
156
docs/DEPLOYABLE_RUNTIME_CONTRACT.md
Normal file
156
docs/DEPLOYABLE_RUNTIME_CONTRACT.md
Normal file
@@ -0,0 +1,156 @@
|
||||
# Deployable Runtime Image Contract
|
||||
|
||||
## Purpose
|
||||
|
||||
Define the minimum deployable runtime contract for backend and frontend images.
|
||||
This document is the canonical source for what must be present, what must not
|
||||
be present, and what behavior deployment environments can rely on.
|
||||
|
||||
This contract supports issue PP-58 and establishes a baseline for future
|
||||
automation work under epic #66.
|
||||
|
||||
## Scope
|
||||
|
||||
Included:
|
||||
|
||||
- Backend deployable runtime image requirements.
|
||||
- Frontend deployable runtime image requirements.
|
||||
- Runtime entrypoint, ports, health behavior, startup behavior, and environment
|
||||
contracts.
|
||||
- Explicitly disallowed non-runtime tooling classes in deployable images.
|
||||
|
||||
Excluded:
|
||||
|
||||
- CI workflow rewiring.
|
||||
- Test execution redesign.
|
||||
- New runtime hardening implementations not required to define contract.
|
||||
|
||||
## Backend Runtime Contract
|
||||
|
||||
### Runtime Artifact Definition
|
||||
|
||||
- Container build source: `Dockerfile.backend`.
|
||||
- Runtime base image: `python:3.14-slim`.
|
||||
- Runtime process: `uvicorn main:app --host 0.0.0.0 --port 8000`.
|
||||
- Exposed runtime port: `8000`.
|
||||
|
||||
### Required Runtime Dependencies
|
||||
|
||||
The runtime artifact must include versions compatible with:
|
||||
|
||||
- `fastapi==0.120.2`
|
||||
- `psycopg==3.2.12`
|
||||
- `sqlalchemy==2.0.44`
|
||||
- `uvicorn==0.38.0`
|
||||
|
||||
The lockfile in `backend/uv.lock` is the dependency source of truth.
|
||||
|
||||
### Required Runtime Environment Contract
|
||||
|
||||
- `DATABASE_URL` is required.
|
||||
- Accepted form: `postgresql://...` or SQLAlchemy async form.
|
||||
- Runtime normalization to async psycopg dialect is performed in
|
||||
`backend/src/backend/database.py`.
|
||||
- `BACKEND_REQUIRED_PYTHON` is optional and defaults to `3.14`.
|
||||
|
||||
### Backend Health and Startup Behavior
|
||||
|
||||
- Startup must fail fast if runtime policy checks fail.
|
||||
- Source: `backend/src/backend/main.py` lifecycle (`lifespan`) validation.
|
||||
- Health endpoint contract:
|
||||
- `GET /health` returns `200` with `{"status":"healthy","database":"connected"}`
|
||||
when database probe succeeds.
|
||||
- `GET /health` returns `503` with
|
||||
`{"status":"unhealthy","database":"disconnected"}` when probe fails.
|
||||
- Compatibility diagnostics endpoint:
|
||||
- `GET /compatibility` reports policy and package compatibility status.
|
||||
|
||||
### Backend Runtime Checklist
|
||||
|
||||
- [ ] Runtime image built from `Dockerfile.backend`.
|
||||
- [ ] Runtime process is uvicorn serving `main:app` on `0.0.0.0:8000`.
|
||||
- [ ] `DATABASE_URL` is set in deployment runtime.
|
||||
- [ ] `GET /health` behavior matches contract.
|
||||
- [ ] Startup fails on runtime policy mismatch.
|
||||
- [ ] Deployable artifact excludes CI-only and test-only tooling classes.
|
||||
|
||||
## Frontend Runtime Contract
|
||||
|
||||
### Frontend Runtime Artifact Definition
|
||||
|
||||
- Container build source: `Dockerfile.frontend` (target `production`).
|
||||
- Runtime base image: `nginx:alpine`.
|
||||
- Runtime process: `nginx -g "daemon off;"`.
|
||||
- Exposed runtime port: `80`.
|
||||
- Runtime artifact payload: static assets from `/app/dist` copied to
|
||||
`/usr/share/nginx/html`.
|
||||
|
||||
### Frontend Runtime Entry and Routing Contract
|
||||
|
||||
- Nginx configuration source: `frontend/nginx.conf`.
|
||||
- SPA routing behavior must use fallback to `index.html` for unknown routes.
|
||||
- API requests under `/api/` are proxied to backend service endpoint
|
||||
`http://backend:8000/` in compose deployments.
|
||||
|
||||
### Frontend Health and Startup Behavior
|
||||
|
||||
- Startup expectation: nginx process starts and serves static assets on port 80.
|
||||
- Runtime health expectation for deployment checks:
|
||||
- `GET /` should return `200` and serve frontend entry document.
|
||||
- API proxy readiness is dependent on backend runtime availability.
|
||||
|
||||
### Frontend Runtime Environment Contract
|
||||
|
||||
- No required runtime environment variables are defined for nginx static serving.
|
||||
- Build-time frontend mode is production-oriented and not part of runtime env
|
||||
contract.
|
||||
|
||||
### Frontend Runtime Checklist
|
||||
|
||||
- [ ] Runtime image built from `Dockerfile.frontend` production target.
|
||||
- [ ] Runtime process is nginx serving on port 80.
|
||||
- [ ] SPA route fallback behavior is present.
|
||||
- [ ] `/api/` proxy behavior aligns with backend service wiring.
|
||||
- [ ] Deployable artifact excludes CI-only and test-only tooling classes.
|
||||
|
||||
## Disallowed Tooling Classes in Deployable Runtime Images
|
||||
|
||||
Deployable runtime artifacts must not include tooling classes that are only
|
||||
needed for CI, validation, or local development workflows.
|
||||
|
||||
Disallowed classes:
|
||||
|
||||
- Linters and formatters (example: ruff, eslint, prettier).
|
||||
- Type checking and static analysis tooling (example: pyright, vue-tsc).
|
||||
- Test frameworks and test drivers (example: pytest, vitest, playwright).
|
||||
- Browser test binaries and CI runner helper tools.
|
||||
- Build-only package managers and build toolchains not needed at runtime.
|
||||
|
||||
Note:
|
||||
|
||||
- Multi-stage builds may use these tools in build stages.
|
||||
- These tools must not be required by or present in final deployable runtime
|
||||
image layers.
|
||||
|
||||
## Acceptance Criteria Traceability (PP-58)
|
||||
|
||||
1. Backend runtime requirements are documented and approved.
|
||||
- Covered by: "Backend Runtime Contract" and backend checklist.
|
||||
2. Frontend runtime requirements are documented and approved.
|
||||
- Covered by: "Frontend Runtime Contract" and frontend checklist.
|
||||
3. Runtime contracts include health endpoint expectations and startup behavior.
|
||||
- Covered by: backend health/startup section and frontend health/startup
|
||||
section.
|
||||
4. Non-runtime tool classes are explicitly excluded from deployable image
|
||||
definition.
|
||||
- Covered by: "Disallowed Tooling Classes in Deployable Runtime Images".
|
||||
|
||||
## Future Enforcement Hooks (Out of Scope for PP-58)
|
||||
|
||||
Potential follow-up automation under epic #66:
|
||||
|
||||
- Policy checks validating final image layers do not include disallowed tooling
|
||||
classes.
|
||||
- Contract tests that assert documented health/startup behavior.
|
||||
- CI checks that verify Dockerfile target boundaries remain aligned with this
|
||||
contract.
|
||||
Reference in New Issue
Block a user