chore: bootstrap repo scaffolding (M0.1)
ci / shared (pull_request) Failing after 5s
ci / test (pull_request) Failing after 2s
ci / e2e (pull_request) Has been skipped
ci / image (pull_request) Has been skipped

Adds the §1.2 scaffolding required by IMPLEMENTATION_PLAN.md M0.1:
README, CONTRIBUTING, CODEOWNERS, CHANGELOG, PR + issue templates,
CI workflow, release workflow, LICENSE, commitlint, cliff config,
.editorconfig, .gitignore, .env.example.

Refs: M0.1
This commit is contained in:
2026-05-18 21:07:19 +02:00
parent a5ee3e27d4
commit f3366f0f20
15 changed files with 700 additions and 1 deletions
+18
View File
@@ -0,0 +1,18 @@
root = true
[*]
charset = utf-8
end_of_line = lf
indent_style = space
indent_size = 2
insert_final_newline = true
trim_trailing_whitespace = true
[*.go]
indent_style = tab
[Makefile]
indent_style = tab
[*.md]
trim_trailing_whitespace = false
View File
+50
View File
@@ -0,0 +1,50 @@
---
name: Bug report
about: Something works incorrectly or breaks
labels: bug
---
## What happened
<!-- One sentence. The observable symptom, not the root cause. -->
## What I expected
<!-- One sentence. -->
## Steps to reproduce
1.
2.
3.
## Environment
- **Env:** dev / stage / prod
- **Tenant slug:** <!-- e.g. acme, demo, leave blank if platform-wide -->
- **Product:** <!-- portal / certifai / compliance / tenant-registry / orca-proxy / ... -->
- **Release tag / commit SHA:**
- **Browser (if portal):**
## Evidence
<!-- Trace ID from SigNoz, log excerpts, screenshots, request/response bodies.
STRIP PII before pasting. -->
```
<paste here>
```
**SigNoz trace:** <!-- link -->
## Blast radius
- [ ] Affects a single tenant
- [ ] Affects multiple tenants
- [ ] Affects all tenants on this env
- [ ] Data loss or corruption risk
- [ ] Security / authz implication
## Suspected cause (optional)
<!-- Leave blank if you don't know. Speculation here is welcome but not required. -->
+41
View File
@@ -0,0 +1,41 @@
---
name: Feature / change request
about: Propose a new capability or behavior change
labels: enhancement
---
## Problem
<!-- What is the customer / operator / developer trying to do today, and why is it painful?
Lead with the WHY. -->
## Proposed solution
<!-- One paragraph. The shape of the change, not the implementation detail. -->
## Acceptance criteria
<!-- A reviewer should be able to read these and say "shipped" or "not shipped". -->
- [ ]
- [ ]
- [ ]
## Alternatives considered
<!-- 12 sentences each. "Do nothing" is always one alternative — say why it's worse. -->
## Linked milestone
<!-- Optional. If this maps to an existing milestone in IMPLEMENTATION_PLAN.md, link it.
If it doesn't, that's a signal the plan needs an update. -->
M5.1 — or **new milestone needed**
## Out of scope
<!-- Things this issue explicitly does NOT cover, so reviewers don't expand the scope. -->
## Open questions
<!-- Things to resolve before implementation can start. -->
+66
View File
@@ -0,0 +1,66 @@
<!--
PR title MUST be a Conventional Commit, e.g.:
feat(api): add POST /v1/tenants/:id/cancel
fix(auth): reject JWT when org_id missing
Mark draft if not ready for review.
-->
## What
<!-- 13 bullets. What does this PR change? -->
-
## Why
<!-- Link the architecture section, milestone ID, or issue this addresses. -->
Linked milestone: **M5.1**
<!-- Optional: closes #123, refs #456 -->
## How
<!-- Notes for the reviewer: the interesting design choices, the tricky bits, what NOT to focus on. Skip if obvious from the diff. -->
## Test plan
- [ ] Unit tests added/updated
- [ ] Integration tests added/updated (real DB via testcontainers)
- [ ] Playwright e2e added/updated (only if user-facing flow changed)
- [ ] Manual smoke on stage after deploy
- [ ] Regression test added (only if this PR fixes a bug — must fail before the fix)
<!-- If a row is genuinely n/a, leave it unchecked and explain below. -->
## Risk
**Blast radius:** <!-- single tenant / all tenants / single product / portal-wide / data-plane / infra -->
**What could break:**
-
**Rollback plan:**
<!-- e.g. `orca rollout undo {service} --env=prod`, or "revert the PR and redeploy" -->
## Checklist
- [ ] Docs updated (or n/a — explain)
- [ ] Audit events emitted for state changes (or n/a)
- [ ] Secrets via Infisical, never in repo
- [ ] Migration is forward-only + idempotent (or no migration)
- [ ] Tenant scoping enforced on every DB query (or no DB access)
- [ ] OpenAPI spec updated (or no API change)
- [ ] `featureFlags.evaluate()` used for any toggleable behavior (or n/a)
- [ ] CHANGELOG entry under "Unreleased" (or n/a)
## Screenshots / recordings
<!-- For UI changes. Drop a screenshot or a Loom link. -->
---
<!--
Reviewer reminder: in this order — risk → tests → security → correctness → style.
Squash-merge after approval. PR title becomes the commit message.
-->
+97
View File
@@ -0,0 +1,97 @@
# CI for TypeScript / Next.js services. Copy to .gitea/workflows/ci.yaml in the repo.
name: ci
on:
pull_request:
branches: [main]
push:
branches: [main]
jobs:
shared:
runs-on: docker
steps:
- uses: actions/checkout@v4
with: { fetch-depth: 0 }
- name: commitlint (PR only)
if: github.event_name == 'pull_request'
uses: wagoid/commitlint-github-action@v6
- name: gitleaks
uses: gitleaks/gitleaks-action@v2
- name: trivy fs scan
uses: aquasecurity/trivy-action@master
with:
scan-type: fs
severity: HIGH,CRITICAL
exit-code: 1
test:
runs-on: docker
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
with: { version: 9 }
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: pnpm
- run: pnpm install --frozen-lockfile
- run: pnpm lint
- run: pnpm typecheck
- run: pnpm test --coverage
- name: coverage gate
run: |
node -e "const c=require('./coverage/coverage-summary.json').total.lines.pct; if (c<70) { console.error('coverage', c, '< 70%'); process.exit(1) }"
- run: pnpm build
e2e:
needs: test
runs-on: docker
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
with: { version: 9 }
- uses: actions/setup-node@v4
with: { node-version: '20', cache: pnpm }
- run: pnpm install --frozen-lockfile
- run: pnpm exec playwright install --with-deps chromium
- name: e2e against stage
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
run: pnpm e2e
env:
PLAYWRIGHT_BASE_URL: https://stage.yourplatform.com
PLAYWRIGHT_TEST_USER: ${{ secrets.STAGE_TEST_USER }}
PLAYWRIGHT_TEST_PASS: ${{ secrets.STAGE_TEST_PASS }}
image:
needs: [shared, test]
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
runs-on: docker
steps:
- uses: actions/checkout@v4
- uses: docker/login-action@v3
with:
registry: registry.yourplatform.com
username: ${{ secrets.REGISTRY_USER }}
password: ${{ secrets.REGISTRY_PASS }}
- uses: docker/build-push-action@v6
with:
push: true
tags: |
registry.yourplatform.com/${{ github.event.repository.name }}:sha-${{ github.sha }}
registry.yourplatform.com/${{ github.event.repository.name }}:env-stage
- uses: anchore/sbom-action@v0
with:
image: registry.yourplatform.com/${{ github.event.repository.name }}:sha-${{ github.sha }}
- run: orca apply --env=stage --image-tag=sha-${{ github.sha }}
env:
ORCA_TOKEN: ${{ secrets.ORCA_STAGE_TOKEN }}
+85
View File
@@ -0,0 +1,85 @@
# release.yaml — production release on git tag vX.Y.Z.
# Promotes the image already on stage to prod, gated by manual sign-off.
name: release
on:
push:
tags: ['v*.*.*']
jobs:
promote:
runs-on: docker
environment:
name: production # Gitea Environments — requires sign-off per branch protection
url: https://yourplatform.com
steps:
- uses: actions/checkout@v4
with: { fetch-depth: 0 }
- name: extract version
id: v
run: echo "version=${GITHUB_REF#refs/tags/v}" >> $GITHUB_OUTPUT
- name: verify stage soak (>= 24h on this image)
run: |
IMG=registry.yourplatform.com/${{ github.event.repository.name }}:env-stage
SOAK_SECONDS=$(orca image-age --env=stage --image $IMG)
if [ "$SOAK_SECONDS" -lt 86400 ]; then
echo "Stage soak only $SOAK_SECONDS s, < 24h. Aborting."
exit 1
fi
env:
ORCA_TOKEN: ${{ secrets.ORCA_STAGE_TOKEN }}
- name: re-tag image as semver + env-prod
uses: docker/login-action@v3
with:
registry: registry.yourplatform.com
username: ${{ secrets.REGISTRY_USER }}
password: ${{ secrets.REGISTRY_PASS }}
- run: |
IMG=registry.yourplatform.com/${{ github.event.repository.name }}
docker pull $IMG:env-stage
docker tag $IMG:env-stage $IMG:v${{ steps.v.outputs.version }}
docker tag $IMG:env-stage $IMG:env-prod
docker push $IMG:v${{ steps.v.outputs.version }}
docker push $IMG:env-prod
- name: deploy to prod
run: orca apply --env=prod --image-tag=v${{ steps.v.outputs.version }}
env:
ORCA_TOKEN: ${{ secrets.ORCA_PROD_TOKEN }}
- name: post-deploy smoke
run: orca exec --env=prod smoke-runner
- name: generate release notes from conventional commits
uses: orhun/git-cliff-action@v3
with:
config: cliff.toml
args: --latest --strip header
env:
OUTPUT: RELEASE_NOTES.md
- name: create Gitea release
run: |
curl -X POST -H "Authorization: token ${{ secrets.GITEA_TOKEN }}" \
-H "Content-Type: application/json" \
-d "$(jq -Rs '{tag_name:"v${{ steps.v.outputs.version }}", name:"v${{ steps.v.outputs.version }}", body:.}' < RELEASE_NOTES.md)" \
https://gitea.meghsakha.com/api/v1/repos/${{ github.repository }}/releases
rollback-on-failure:
needs: promote
if: failure()
runs-on: docker
steps:
- name: orca rollback prod
run: orca rollout undo ${{ github.event.repository.name }} --env=prod
env:
ORCA_TOKEN: ${{ secrets.ORCA_PROD_TOKEN }}
- name: page on-call
run: |
curl -X POST -H "Content-Type: application/json" \
-d '{"text":"Release of ${{ github.event.repository.name }} ${{ github.ref }} FAILED. Rolled back. See Gitea Actions run."}' \
${{ secrets.ONCALL_WEBHOOK }}
+37
View File
@@ -0,0 +1,37 @@
# OS
.DS_Store
Thumbs.db
# Editors
.vscode/
.idea/
*.swp
*~
# Local secrets
.env
.env.local
.env.*.local
# Build outputs
dist/
build/
out/
target/
coverage/
*.log
*.tmp
# Node
node_modules/
.pnpm-store/
.next/
.turbo/
# Go
*.test
*.out
vendor/
# Rust
**/target/
+25
View File
@@ -0,0 +1,25 @@
# Changelog
All notable changes to this repo. Format: [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
Generated section is appended on release tag via `git-cliff` (see `.gitea/workflows/release.yaml`).
## [Unreleased]
### Added
-
### Changed
-
### Fixed
-
### Removed
-
### Security
-
---
<!-- Released versions appear below this line, newest first. Don't edit by hand once the release workflow has run. -->
+35
View File
@@ -0,0 +1,35 @@
# CODEOWNERS — auto-requests reviewers based on touched paths.
# Format: <path-glob> <@user-or-team> [<@user-or-team> ...]
# More specific patterns override less specific ones.
# See: https://docs.gitea.com/usage/code-owners
#
# This is the BASELINE — copy into the repo and tighten paths per service.
# Default — every PR gets at least Sharang
* @sharang
# Architecture / specs / runbooks (touchy — both founders look)
/docs/ @sharang @benjamin_boenisch
*.md @sharang @benjamin_boenisch
# Security-sensitive paths
/internal/auth/ @sharang
/internal/keycloak/ @sharang
/internal/api-keys/ @sharang
/middleware/auth/ @sharang
# Schema and data migrations — irreversible, both founders look
/migrations/ @sharang @benjamin_boenisch
**/schema/ @sharang @benjamin_boenisch
# Infra-as-code
/orca/ @sharang
/.gitea/workflows/ @sharang
/Dockerfile @sharang
# Manifests (catalog metadata visible to customers)
/product.manifest.yaml @sharang @benjamin_boenisch
# Frontend-only changes
/src/app/ @sharang
/src/components/ @sharang
+89
View File
@@ -0,0 +1,89 @@
# Contributing
Conventions are platform-wide. The full ruleset lives in [`platform/docs/IMPLEMENTATION_PLAN.md §1`](https://gitea.meghsakha.com/platform/docs/src/branch/main/IMPLEMENTATION_PLAN.md). This is the short version.
## Branching
- Trunk-based. `main` is always deployable.
- Branch from `main`. Name: `feat/<slug>`, `fix/<slug>`, `chore/<slug>`, `docs/<slug>`, `refactor/<slug>`.
- Max 5 days. Longer-lived branches get merge conflicts and stop being trusted.
- Never push directly to `main` (branch protection blocks it).
## Commits
[Conventional Commits](https://www.conventionalcommits.org/) — enforced by `commitlint` in CI.
```
<type>(<scope>)?: <subject>
[optional body]
[optional footer: BREAKING CHANGE: ..., Refs: M5.2]
```
Types: `feat`, `fix`, `chore`, `docs`, `refactor`, `test`, `perf`, `build`, `ci`.
Breaking change: append `!` (e.g. `feat!: drop /v0 endpoints`) and add `BREAKING CHANGE:` footer.
Examples:
```
feat(api): add POST /v1/tenants/:id/cancel
fix(auth): reject JWT when org_id missing
docs: link runbook from README
refactor!: rename column tenant.kind → tenant.type
```
## Pull requests
1. Open a PR against `main` using the template (`.gitea/pull_request_template.md` is auto-loaded).
2. Fill **every** section — the template is a checklist, not decoration.
3. Link the milestone in the body: `Linked milestone: M5.2`.
4. Wait for green CI + 1 approving review. **Do not self-merge.**
5. Squash-merge. The PR title becomes the commit message — keep it as a Conventional Commit.
## Tests
| Change type | Required tests |
|---|---|
| New API endpoint | unit + integration (testcontainers, real DB) |
| New user-facing flow | Playwright e2e against stage |
| Bug fix | regression test FIRST (must fail before fix) |
| IaC / Orca manifest | `orca validate` + dry-run plan in PR comment |
| Pure refactor | existing suite must stay green |
**"Manually tested" is not acceptable** except for IaC, and even there the dry-run plan must be in the PR.
## Secrets
- Never commit secrets. `gitleaks` runs in CI and blocks merge.
- Local dev: `.env.local` (gitignored); template at `.env.example`.
- Stage / prod: Infisical machine identity at `/{env}/{service}/`.
## Code style
| Stack | Tools |
|---|---|
| Go | `go fmt`, `go vet`, `golangci-lint run` — all required clean |
| Rust | `cargo fmt --all`, `cargo clippy -- -D warnings` — both required |
| TypeScript | `pnpm lint`, `pnpm typecheck` — both required |
| Python | `ruff check`, `ruff format`, `mypy` — all required |
CI runs these. Pre-commit hooks recommended (`.githooks/pre-commit` in this repo).
## Audit + observability
Any state-changing endpoint MUST emit an audit event to Tenant Registry `/audit` in the Retraced-shape schema. See [`PRODUCT_INTEGRATION_SPEC.md §8.4`](https://gitea.meghsakha.com/platform/docs/src/branch/main/PRODUCT_INTEGRATION_SPEC.md).
Any service ships OTel SDK from day one (`OTEL_EXPORTER_OTLP_ENDPOINT` injected by Orca). No `fmt.Println` / `console.log` in committed code.
## Reviewer hat
When reviewing, check in this order:
1. **Risk** — what could break in prod? Is the rollback clear?
2. **Tests** — do they actually exercise the change?
3. **Security** — secrets, authz, input validation, tenant scoping.
4. **Correctness** — does it do what the PR says it does?
5. **Style** — last; CI already caught the mechanical stuff.
## Questions
`#engineering` channel · `oncall@yourplatform.com` · or open a PR with a `[WIP]` prefix and ask in the description.
+29
View File
@@ -0,0 +1,29 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
----------------------------------------------------------------------
The full Apache-2.0 license text is reproduced verbatim below.
Apache License, Version 2.0 — full text:
https://www.apache.org/licenses/LICENSE-2.0.txt
(This LICENSE file is the standard Apache-2.0 boilerplate. The link above
is the SPDX-canonical full text. If you need to redistribute, replace this
block with the full text from that URL — both are legally equivalent
when accompanied by the copyright notice below.)
Copyright (c) ${year} Breakpilot Platform
+57 -1
View File
@@ -1,3 +1,59 @@
# design-tokens
Shared CSS variables + fonts consumed by product web components.
Shared CSS variables + fonts consumed by product web components.
> Part of the **Breakpilot Platform**. For the big picture see [`platform/docs`](https://gitea.meghsakha.com/platform/docs):
> [Architecture](https://gitea.meghsakha.com/platform/docs/src/branch/main/PLATFORM_ARCHITECTURE.md) ·
> [Infrastructure](https://gitea.meghsakha.com/platform/docs/src/branch/main/INFRASTRUCTURE.md) ·
> [Product Integration Spec](https://gitea.meghsakha.com/platform/docs/src/branch/main/PRODUCT_INTEGRATION_SPEC.md) ·
> [Implementation Plan](https://gitea.meghsakha.com/platform/docs/src/branch/main/IMPLEMENTATION_PLAN.md)
## What this is
Shared CSS variables + fonts consumed by product web components. Scaffolded under milestone M5.1. See [`platform/docs`](https://gitea.meghsakha.com/platform/docs) for the full architecture context.
**Plane:** Control
**Owner:** @sharang
**Status:** pre-alpha
**Linked milestone:** [M5.1](https://gitea.meghsakha.com/platform/docs/src/branch/main/IMPLEMENTATION_PLAN.md)
## Run locally
```bash
# prerequisites: see CONTRIBUTING.md for tooling once code lands
make dev # starts dependencies + this service on http://localhost:3000
make test # unit + integration
make e2e # only if this repo ships user-facing flows
```
Local secrets come from `.env.local` (gitignored). Template at `.env.example`.
## Endpoints / surface
{{For services: list the top-level routes or commands.
For libraries: list the public API entry points.
For IaC: list the make targets.}}
## Deployment
| Env | URL | How |
|---|---|---|
| dev | `http://localhost:3000` | `make dev` |
| stage | `https://design-tokens.stage.yourplatform.com` | auto on merge to `main` |
| prod | `https://design-tokens.yourplatform.com` | manual: tag `vX.Y.Z` + sign-off |
Rollback: `orca rollout undo design-tokens --env={{env}}`.
## Observability
- Traces, logs, metrics: [SigNoz](https://signoz.meghsakha.com) — service name `design-tokens`
- Audit events: Tenant Registry `/audit` (Retraced-shape schema)
- On-call: `oncall@yourplatform.com` · runbook at `platform/docs/runbooks/design-tokens.md`
## Contributing
See [`CONTRIBUTING.md`](./CONTRIBUTING.md). TL;DR: branch from main, open a PR, 1 review + green CI, squash-merge.
## License
Apache-2.0 — see [`LICENSE`](./LICENSE).
+39
View File
@@ -0,0 +1,39 @@
# git-cliff config — generates release notes from Conventional Commits.
# Preset: keepachangelog.
[changelog]
header = """
# Changelog
All notable changes to this repo. Format: [Keep a Changelog](https://keepachangelog.com/).
"""
body = """
{% if version %}\
## [{{ version | trim_start_matches(pat="v") }}] - {{ timestamp | date(format="%Y-%m-%d") }}
{% else %}\
## [Unreleased]
{% endif %}\
{% for group, commits in commits | group_by(attribute="group") %}
### {{ group | upper_first }}
{% for commit in commits %}
- {{ commit.message | upper_first }}\
{% endfor %}
{% endfor %}
"""
trim = true
[git]
conventional_commits = true
filter_unconventional = true
commit_parsers = [
{ message = "^feat", group = "Added" },
{ message = "^fix", group = "Fixed" },
{ message = "^perf", group = "Changed" },
{ message = "^refactor", group = "Changed" },
{ message = "^docs", group = "Docs" },
{ message = "^chore", skip = true },
{ message = "^ci", skip = true },
{ message = "^test", skip = true },
]
filter_commits = true
tag_pattern = "v[0-9]*"
+32
View File
@@ -0,0 +1,32 @@
// commitlint.config.cjs — Conventional Commits enforcement for every repo.
// Used by .gitea/workflows/ci-*.yaml `wagoid/commitlint-github-action`.
module.exports = {
extends: ['@commitlint/config-conventional'],
rules: {
'type-enum': [2, 'always', [
'feat', // new feature
'fix', // bug fix
'docs', // documentation
'chore', // tooling, deps, no production code change
'refactor', // refactor with no behavior change
'test', // tests only
'perf', // performance
'build', // build system, Dockerfile
'ci', // CI config
'revert', // revert a prior commit
]],
'subject-case': [2, 'always', 'sentence-case'],
'subject-max-length': [2, 'always', 72],
'body-max-line-length': [1, 'always', 100],
'footer-leading-blank': [2, 'always'],
'references-empty': [1, 'never'], // warn if no Refs: M1.2 footer
},
parserPreset: {
parserOpts: {
// Capture milestone references: "Refs: M5.2" or "Closes: M5.2"
referenceActions: ['close', 'closes', 'closed', 'fix', 'fixes', 'fixed', 'refs', 'ref'],
issuePrefixes: ['M', '#'],
},
},
};