The standard for how an Opptra app is set up, aligned, changed, reviewed, and deployed.
service.yaml holds the facts: production project, region, workloads/components, capabilities, and any unmet platform gaps. mapping.yaml decides the files, the CI, the deploy, and the agent rules. odlc (scripts/odlc.py) and scripts/generate.py apply that decision in phases (check, status, init-runtime, add-data, add-tests, sync-infra). People do not hand-copy a hardcoded pipeline.
main is the default branch. A feature pull request targets main. Merging to main does not deploy.
A direct push to staging deploys the shared staging project. staging has no pull request. main is not merged into staging.
A pull request from main into production deploys prod_project from service.yaml.
| Path | Who it is for |
|---|---|
| docs/workflows.md | Which skill to use. GitHub Pages publishes docs/ from main with a left page index and a right heading index. |
opptra/agent-skills (opptra, create-app, change-app, align-app, feature, bug) |
The agent skills that drive the SDLC |
| odlc | Phase CLI (check, status, init-runtime, add-data, add-tests, sync-infra). discover and sync are aliases for discover-infra and sync-infra. |
| docs/new-app.md | Creating a new app |
| docs/align.md | Aligning an existing repository |
| docs/feature.md | Reviewing a feature |
| docs/bug.md | Reviewing a bug |
| docs/gcp-bootstrap.md | The one-time GCP setup |
| docs/bind.md | What to add on GitHub, which bind script you run, and which script to send to someone with production access |
| modules/ | Terraform recipes. The generator copies the ones an app uses into that app's infra/modules/. |
| scripts/ | The generator, the checks, and the three Python files a deploy runs from the app checkout. |
| .github/workflows/ | Reusable CI and deploy workflows. An app calls them. It does not copy them. |
| skeletons/ | Starting files copied into a new app. |
| rules/source/ | Agent rule text, compiled into an app from the capabilities in service.yaml. |
Apps Script is not generated. When a request includes needs outside the current catalog, the skill scaffolds all supported parts and records the gap under unmet with a recommendation.
| Facts | Result |
|---|---|
ui and api (staff-dashboard) |
FastAPI, Vite, passing /api/health and UI tests, Python CI, frontend CI, Terraform plan, Cloud Run deploy |
api (http-api) |
The same without the UI or frontend CI |
job / scheduled-jobs |
One image, one or many Cloud Run Jobs with per-job commands and Cloud Scheduler crons (enabled jobs only), optional shared-secret webhook receiver, passing runner tests |
worker |
A long-running VM worker, structured logging, a passing test, Python CI, an image push that does not restart the VM |
config |
A README and a CI check. No deploy |
database: postgres |
Cloud SQL Postgres 16, SQLAlchemy + Alembic (db.py), Secret Manager password, IAM |
database: firestore |
Default Firestore Native DB IAM, firestore_state.py (lease locks, heartbeats, idempotency, generation pointers) |
bucket: private |
Private GCS bucket (<project>-<name>-assets), uniform access, storage helper |
queue |
Cloud Tasks queue and enqueuer IAM |
secrets |
Secret Manager shells named <prefix>-<ENV_NAME>. No values in the repo or in state. The workload grants its own runtime account. |
alerts |
Log-based alert policy for failed job runs / unhandled severity>=ERROR logs |