From 8433024e79818ed6cce7176d056fc5cf17932cea Mon Sep 17 00:00:00 2001 From: zaebee Date: Mon, 19 Oct 2026 22:45:01 +0300 Subject: [PATCH 01/17] docs: add org profile refresh design --- .../2026-10-19-org-profile-refresh-design.md | 148 ++++++++++++++++++ 1 file changed, 148 insertions(+) create mode 100644 docs/superpowers/specs/2026-10-19-org-profile-refresh-design.md diff --git a/docs/superpowers/specs/2026-10-19-org-profile-refresh-design.md b/docs/superpowers/specs/2026-10-19-org-profile-refresh-design.md new file mode 100644 index 0000000..f8c37db --- /dev/null +++ b/docs/superpowers/specs/2026-10-19-org-profile-refresh-design.md @@ -0,0 +1,148 @@ +# Org profile refresh — design + +Date: 2026-10-19 +Repo: `Ownima/.github` (local `org-profile/`) +Status: approved for implementation + +## Context + +`Ownima/.github` is the public org profile plus `RELEASING.md`. The profile +was last overhauled on 2026-06-10, before the 2026-08-28 renames +(`rider-web` → `booking-web`, `ownima-admin` → `owner-admin`) and before +`rider-app`, `support-agent`, `pricing-oracle`, `ownima-blog` and +`ownima-workspace` became part of the org. It now links to a non-existent +repository, misses half the product surface, and describes the React 18 / +single-Vue-app world. + +Audience: primarily the Ownima team and AI agents; secondarily external +visitors of `github.com/Ownima`. Product code is private except +`pricing-oracle` and `.github`. + +GitHub community health for the repo is 37%: no security, contribution, +support or conduct files, no issue/PR templates. + +## Goals + +- Make the profile truthful: names, links, stacks, repositories. +- Keep repository links (they are useful for members and agents) and label + private ones clearly. +- Give AI agents a single entry point. +- Raise the repository to a healthy community baseline. +- Prevent the same drift from recurring with an automated link check. + +## Non-goals + +- No code changes in product repositories. +- No repository visibility changes. +- No localization of the profile (English only). +- No stage or internal host names in the public profile. + +## Decisions + +| Question | Decision | +|---|---| +| Audience | Team and AI agents first, external visitors second | +| Private repo links | Keep, mark `(private)`, explain they work for org members | +| Scope | Docs + community files + GitHub settings | +| Team block | Keep, fix: `@zaebee`, `@ownima-ivan`, `@ReD1KC`; drop `@AlexandrovTLG` | +| Profile language | English | +| Canonical domains | `ownima.com`, `rider.ownima.com`, `booking.ownima.com`, `beta.ownima.com`, `admin.ownima.com` | +| Contacts | `contact@ownima.com`; vulnerabilities via GitHub advisories | +| `beta.ownima.com` | Replaces `app.ownima.com` in the profile | + +## Deliverables + +### 1. `profile/README.md` + +1. Ownima — one sentence. +2. Live products — the five canonical domains, no stage hosts. +3. Platform — owner/rider/admin roles, multilingual, reservations, pricing, + wallet, background jobs. +4. Repositories — table of repo, role, stack; private entries carry + `(private)`; one line explaining members-only links. +5. Architecture — compact Mermaid diagram: frontends → API → + PostgreSQL/OpenSearch/Redis/MinIO → workers; recognition, support-agent + and pricing-oracle shown separately. +6. For AI agents — entry point `Ownima/ownima-workspace`, then `AGENTS.md` + in each repository; `CLAUDE.md` only imports `AGENTS.md`. +7. Releasing — link to `RELEASING.md`. +8. Team — `@zaebee` (backend/architecture), `@ownima-ivan` (product/QA), + `@ReD1KC` (frontend). +9. Contact — `contact@ownima.com` and GitHub advisories. + +### 2. Other repository files + +| File | Change | +|---|---| +| `README.md` | Purpose, contents, how to propose changes | +| `RELEASING.md` | Four release-please repos; correct force-version guidance; App token; note that `rider-app` deploys on Vercel | +| `SECURITY.md` | Reporting via GitHub advisories and `contact@ownima.com` | +| `SUPPORT.md` | Support channels and issue routing | +| `CONTRIBUTING.md` | Branches, conventional commits, PR gates, cross-repo routing | +| `CODE_OF_CONDUCT.md` | Contributor Covenant 2.1, enforcement contact `contact@ownima.com` | +| `ISSUE_TEMPLATE/bug.yml`, `feature.yml`, `config.yml` | Org-wide issue templates | +| `PULL_REQUEST_TEMPLATE.md` | Description and verification checklist | +| `.gitignore` | Minimal, replaces the Python template | + +### 3. GitHub settings + +Organization: description `Vehicle rental management platform for owners and +riders.`, website `https://ownima.com`, email `contact@ownima.com`. + +Repository metadata (description / homepage / topics): + +| Repo | Description | Homepage | Topics | +|---|---|---|---| +| `owner-api` | Ownima backend: REST API, SAQ workers, Telegram bot, protobuf schema | — | python, fastapi, postgresql, opensearch, saq | +| `owner-web` | Owner dashboard: fleet, reservations, finance, Capacitor mobile | `https://beta.ownima.com` | react, typescript, capacitor, tanstack, tailwindcss | +| `owner-admin` | Internal admin panel: users, operations, analytics | `https://admin.ownima.com` | react, typescript, vitest, tailwindcss | +| `booking-web` | Rider-facing booking storefront for a single owner | `https://booking.ownima.com` | nuxt, vue, typescript, tailwindcss | +| `rider-app` | Multi-owner rental marketplace for riders | `https://rider.ownima.com` | nuxt, vue, typescript, marketplace | +| `ownima-blog` | Astro SEO site for the Ownima Thailand market | — | astro, typescript, seo | +| `pricing-oracle` | Rental pricing market intelligence over REST, A2A and Fetch.ai uAgent | — | python, fastapi, a2a, fetch-ai | +| `support-agent` | AI support agent: knowledge base, n8n workflows and evals | — | python, n8n, anthropic, evals | +| `ansible` | Ownima infrastructure: deploy playbooks, monitoring, runbooks | — | ansible, docker, monitoring, prometheus | +| `ownima-workspace` | Workspace guide and shared agent skills | — | agents, developer-experience | +| `.github` | Org profile, release guide and community health files | — | — | + +Enable private vulnerability reporting where available. Add the `.github` +repository to the org runner group `ci` so the guard workflow can run on the +self-hosted runner. + +### 4. Guard workflow + +`.github/workflows/profile-links.yml`, triggered on PR, push to `main` and +weekly: + +- every `github.com/Ownima/` link in `profile/README.md` resolves + (GitHub App token for private repos); +- every live domain in the profile returns 2xx; +- every non-archived org repository is mentioned in the profile. + +## Acceptance criteria + +- `profile/README.md` contains no reference to `rider-web` or `ownima-admin`. +- All five canonical domains are listed; no `*.ownima.com` stage host appears. +- Each of the ten product/service repositories (all except `.github`) + appears once in the repository table. +- `RELEASING.md` lists exactly the four release-please repositories. +- `gh api repos/Ownima/.github/community/profile` reports the new files and + a health percentage above 80%. +- Guard workflow passes on the PR and on a manual run. +- Existing `LICENSE` is unchanged. + +## Risks + +- Org settings and repository metadata are applied with `gh`; a mistake is + visible org-wide. Each change is listed in the PR body before it is applied. +- GitHub App secrets may not be available to the `.github` repository; if + they are missing, the guard falls back to public-link checking and reports + the private-repo check as skipped instead of failing. +- A Mermaid diagram renders differently across GitHub clients; it stays + small and text-readable in source. + +## Out of scope + +- Making product repositories public. +- Rewriting each repository's README. +- Adding a LICENSE to product repositories. From 59c00accab80e84ddd62a019a002ae6d519eb7ef Mon Sep 17 00:00:00 2001 From: zaebee Date: Mon, 19 Oct 2026 22:59:14 +0300 Subject: [PATCH 02/17] docs: add org profile refresh implementation plan --- .../plans/2026-10-19-org-profile-refresh.md | 806 ++++++++++++++++++ 1 file changed, 806 insertions(+) create mode 100644 docs/superpowers/plans/2026-10-19-org-profile-refresh.md diff --git a/docs/superpowers/plans/2026-10-19-org-profile-refresh.md b/docs/superpowers/plans/2026-10-19-org-profile-refresh.md new file mode 100644 index 0000000..f5e4d22 --- /dev/null +++ b/docs/superpowers/plans/2026-10-19-org-profile-refresh.md @@ -0,0 +1,806 @@ +# Org Profile Refresh Implementation Plan + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** Make `Ownima/.github` a truthful, healthy org profile for the team and AI agents, and add a guard that catches future drift. + +**Architecture:** A layered `profile/README.md` (public products first, internal engineering map second), a refreshed `RELEASING.md`, org-wide community health files, and a small shell guard run by GitHub Actions. GitHub settings and repository metadata are applied with `gh` outside git. + +**Tech Stack:** Markdown, Bash, GitHub CLI, GitHub Actions, Mermaid. + +**Spec:** `docs/superpowers/specs/2026-10-19-org-profile-refresh-design.md` + +--- + +### Task 1: Rewrite the profile README + +**Files:** +- Modify: `profile/README.md` + +- [ ] **Step 1: Replace `profile/README.md` with the content below** + +````markdown +# Ownima — Vehicle Rental Management Platform + +**One platform for rental businesses and their riders: fleet, reservations, pricing and finance.** + +--- + +## Live products + +| Product | URL | Audience | +|---|---|---| +| Ownima | [ownima.com](https://ownima.com) | Public site | +| Rider marketplace | [rider.ownima.com](https://rider.ownima.com) | Riders across all owners | +| Booking storefront | [booking.ownima.com](https://booking.ownima.com) | Riders of one owner | +| Owner cabinet | [beta.ownima.com](https://beta.ownima.com) | Rental owners | +| Admin panel | [admin.ownima.com](https://admin.ownima.com) | Ownima operators | + +--- + +## Platform + +- Three roles: owner, rider, admin, with role-based access control. +- Fleet and vehicle management, images stored in MinIO. +- Reservations with real-time availability and a booking request flow. +- Pricing templates (seasonal, duration-based) and a market pricing oracle. +- Wallet, transactions and financial dashboards. +- Five locales: English, Russian, Thai, Indonesian, Vietnamese. +- Background jobs on a SAQ worker queue. +- AI support drafting and vehicle image recognition. + +--- + +## Repositories + +Product repositories are private; links work for Ownima members. + +| Repository | Role | Stack | +|---|---|---| +| [owner-api](https://github.com/Ownima/owner-api) `(private)` | REST API, workers, Telegram bot, protobuf schema | Python 3.12 · FastAPI · PostgreSQL · OpenSearch · Redis · MinIO · SAQ | +| [owner-web](https://github.com/Ownima/owner-web) `(private)` | Owner dashboard, Capacitor mobile app | React 19 · TypeScript · TanStack · Tailwind 4 · Vite · bun | +| [owner-admin](https://github.com/Ownima/owner-admin) `(private)` | Internal admin panel | React 19 · TanStack Query · Radix · Tailwind 4 · Vitest · bun | +| [booking-web](https://github.com/Ownima/booking-web) `(private)` | Rider storefront for a single owner, embeddable widget | Nuxt 4 · Vue 3 · Pinia · TanStack Vue Query · Tailwind 4 · bun | +| [rider-app](https://github.com/Ownima/rider-app) `(private)` | Multi-owner rental marketplace | Nuxt 4 · Vue 3 · FSD · Pinia · Tailwind 4 · Vercel | +| [support-agent](https://github.com/Ownima/support-agent) `(private)` | AI support drafting, knowledge base, evals | Python 3.12 · Claude · n8n | +| [pricing-oracle](https://github.com/Ownima/pricing-oracle) | Rental pricing market intelligence | Python 3.12 · FastAPI · SQLModel · A2A · Fetch.ai | +| [ownima-blog](https://github.com/Ownima/ownima-blog) `(private)` | SEO site for the Thailand market | Astro 6 · TypeScript · pagefind · bun | +| [ansible](https://github.com/Ownima/ansible) `(private)` | Infrastructure, deployment, monitoring, runbooks | Ansible · Docker · Prometheus · Grafana · Loki | +| [ownima-workspace](https://github.com/Ownima/ownima-workspace) `(private)` | Workspace guide and shared agent skills | Bash · Markdown | + +--- + +## Architecture + +```mermaid +flowchart LR + RA[rider-app] --> API[owner-api] + BW[booking-web] --> API + OW[owner-web] --> API + AD[owner-admin] --> API + API --> PG[(PostgreSQL)] + API --> OS[(OpenSearch)] + API --> RD[(Redis / SAQ)] + API --> MI[(MinIO)] + API --> REC[Recognition] + SA[support-agent] --> N8N[n8n] + PO[pricing-oracle] --> API +``` + +--- + +## For AI agents + +Start at [ownima-workspace](https://github.com/Ownima/ownima-workspace): it holds the +workspace guide and the shared skills. Each repository has an `AGENTS.md` with its own +commands and rules. `CLAUDE.md` only imports `AGENTS.md`. + +--- + +## Releasing + +Release Please derives versions from conventional commits. See [RELEASING.md](../RELEASING.md). + +--- + +## Team + +| Role | GitHub | +|---|---| +| Backend / Architecture | [@zaebee](https://github.com/zaebee) | +| Product / QA | [@ownima-ivan](https://github.com/ownima-ivan) | +| Frontend | [@ReD1KC](https://github.com/ReD1KC) | + +--- + +Contact: **contact@ownima.com** +Security: [private advisories](https://github.com/Ownima/.github/security/advisories/new) +```` + +- [ ] **Step 2: Verify no stale names remain** + +Run: `rg -n "rider-web|ownima-admin|app\.ownima\.com|React 18" profile/README.md` +Expected: no output. + +- [ ] **Step 3: Commit** + +```bash +git add profile/README.md +git commit -m "docs(profile): refresh products, repositories and team" +``` + +--- + +### Task 2: Refresh the root README and RELEASING + +**Files:** +- Modify: `README.md` +- Modify: `RELEASING.md` + +- [ ] **Step 1: Replace `README.md` with the content below** + +````markdown +# Ownima/.github + +Org-wide defaults and documentation for the [Ownima](https://github.com/Ownima) +GitHub organization. + +## Contents + +- [`profile/README.md`](profile/README.md) — organization profile shown on + [github.com/Ownima](https://github.com/Ownima) +- [`RELEASING.md`](RELEASING.md) — release process and conventional commit guide +- [`CONTRIBUTING.md`](CONTRIBUTING.md) — branches, commits and PR rules +- [`SECURITY.md`](SECURITY.md) — how to report a vulnerability +- [`SUPPORT.md`](SUPPORT.md) — where to ask for help +- [`CODE_OF_CONDUCT.md`](CODE_OF_CONDUCT.md) — expected behavior + +## Changing the profile + +Open a pull request against `main`. The `profile-links` workflow checks repository +links, live domains and repository coverage on every PR and once a week. + +## Issues + +Cross-repo and backlog tasks are tracked here as +[GitHub Issues](https://github.com/Ownima/.github/issues). +```` + +- [ ] **Step 2: Replace `RELEASING.md` with the content below** + +````markdown +# Releasing + +Ownima uses [Release Please](https://github.com/googleapis/release-please) to +automate versioning and changelog generation. + +## How it works + +Release Please watches commits on `main` and derives the next version from +conventional commit prefixes: + +| Commit prefix | Version bump | Example | +|---|---|---| +| `fix: ...` | patch | `0.2.28` → `0.2.29` | +| `feat: ...` | minor | `0.2.28` → `0.3.0` | +| `feat!: ...` or `BREAKING CHANGE:` in the body | major | `0.2.28` → `1.0.0` | +| `chore:`, `docs:`, `refactor:`, `ci:`, … | none | no release PR on its own | + +On every push to `main` it either: + +1. creates or updates a release PR titled `chore(main): release X.Y.Z` with an + autogenerated changelog, or +2. tags and releases when that PR is merged. + +## Repositories + +| Repository | Versioning | +|---|---| +| `owner-api` | `release-please-config.json` + `.release-please-manifest.json` (key `ownima-backend`) | +| `owner-web` | `release-please-config.json` + `.release-please-manifest.json` | +| `booking-web` | `release-please-config.json` + `.release-please-manifest.json` | +| `rider-app` | `release-please-config.json` + `.release-please-manifest.json` | + +They use a GitHub App token (`OWNIMA_BOT_APP_ID` + `OWNIMA_BOT_PRIVATE_KEY`) +instead of `GITHUB_TOKEN`, because the organization restricts PR creation for +Actions. `rider-app` builds and deploys on Vercel from `main`. + +## Workflow + +``` +push to main + └─► release-please runs + ├─ no releasable commits → nothing happens + └─ releasable commits found + ├─ release PR already open → updates it + └─ no open release PR → creates one + └─ merge release PR + └─ creates git tag + GitHub Release +``` + +## Tips + +- **Force a version**: put `Release-As: X.Y.Z` as a trailer in a commit on + `main`. Release Please picks it up on the next run. +- **Hold a release**: leave the release PR open; it keeps updating. +- **Non-releasable commits** (`chore:`, `ci:`, `docs:`) do not trigger a + release PR on their own, but they do not reset one that is already open. +```` + +- [ ] **Step 3: Verify RELEASING lists four repositories** + +Run: `rg -c "release-please-config.json" RELEASING.md` +Expected: `4` (table rows; the intro link does not match this string). + +- [ ] **Step 4: Commit** + +```bash +git add README.md RELEASING.md +git commit -m "docs: refresh repo readme and releasing guide" +``` + +--- + +### Task 3: Add security, support and contribution files + +**Files:** +- Create: `SECURITY.md` +- Create: `SUPPORT.md` +- Create: `CONTRIBUTING.md` + +- [ ] **Step 1: Create `SECURITY.md`** + +````markdown +# Security Policy + +## Reporting a vulnerability + +Report vulnerabilities through +[GitHub private advisories](https://github.com/Ownima/.github/security/advisories/new). +If you cannot use GitHub, email **contact@ownima.com**. + +Please include: + +- affected repository and version or commit; +- steps to reproduce; +- impact you believe it has; +- any suggested fix. + +Do not open a public issue for a vulnerability. We aim to acknowledge a report +within two working days and to keep you updated until it is resolved. + +## Supported versions + +Only the latest release of each service is supported. Security fixes are applied +to `main` and released through the normal Release Please flow. +```` + +- [ ] **Step 2: Create `SUPPORT.md`** + +````markdown +# Support + +## Product questions + +Email **contact@ownima.com** or reach the team in the internal chat. + +## Bugs and feature requests + +Open an issue in the repository that owns the behavior: + +| Area | Repository | +|---|---| +| API, workers, data | `Ownima/owner-api` | +| Owner dashboard | `Ownima/owner-web` | +| Internal admin panel | `Ownima/owner-admin` | +| Rider storefront | `Ownima/booking-web` | +| Rider marketplace | `Ownima/rider-app` | +| Support automation | `Ownima/support-agent` | +| Pricing oracle | `Ownima/pricing-oracle` | +| SEO site | `Ownima/ownima-blog` | +| Infrastructure and deploys | `Ownima/ansible` | +| Workspace guide and skills | `Ownima/ownima-workspace` | + +Use this repository only for cross-repo or organization-level issues. + +## Security + +See [SECURITY.md](SECURITY.md). +```` + +- [ ] **Step 3: Create `CONTRIBUTING.md`** + +````markdown +# Contributing + +## Branches + +Use `/-`, for example `fix/1219-time-slot-parse`. The default +branch is `main` in every repository. + +## Commits + +Conventional Commits: `type(scope): subject`. Types in use: `feat`, `fix`, +`refactor`, `chore`, `ci`, `test`, `docs`, `perf`, `style`, `build`, `revert`. + +## Pull requests + +- Keep a PR to one change. +- Link the issue when one exists. +- Make CI green before asking for review: tests, lint, typecheck and build for + the repository you touched. +- A backend request from a frontend repository is an issue on + `Ownima/owner-api`, not a task file in the frontend repository. +- Cross-repository references are full URLs. + +## Types and schemas + +Frontends generate their API types from the backend OpenAPI schema. Never +hand-edit generated directories (`gen`, `gen_types`). Regenerate and commit the +snapshot instead. + +## Where to ask + +See [SUPPORT.md](SUPPORT.md). +```` + +- [ ] **Step 4: Commit** + +```bash +git add SECURITY.md SUPPORT.md CONTRIBUTING.md +git commit -m "docs: add security, support and contributing guides" +``` + +--- + +### Task 4: Add conduct, templates and a minimal gitignore + +**Files:** +- Create: `CODE_OF_CONDUCT.md` +- Create: `ISSUE_TEMPLATE/bug.yml` +- Create: `ISSUE_TEMPLATE/feature.yml` +- Create: `ISSUE_TEMPLATE/config.yml` +- Create: `PULL_REQUEST_TEMPLATE.md` +- Modify: `.gitignore` + +- [ ] **Step 1: Create `CODE_OF_CONDUCT.md` from Contributor Covenant 2.1** + +Run: + +```bash +curl -fsSL https://www.contributor-covenant.org/version/2/1/code_of_conduct/code_of_conduct.md \ + -o CODE_OF_CONDUCT.md +sed -i 's/\[INSERT CONTACT METHOD\]/contact@ownima.com/g' CODE_OF_CONDUCT.md +``` + +Expected: `CODE_OF_CONDUCT.md` is present and contains `contact@ownima.com`. + +- [ ] **Step 2: Create `ISSUE_TEMPLATE/bug.yml`** + +````yaml +name: Bug report +description: Something is broken +labels: [bug] +body: + - type: input + id: repository + attributes: + label: Repository + placeholder: Ownima/owner-api + validations: + required: true + - type: textarea + id: what-happened + attributes: + label: What happened + description: Observed behavior and what you expected instead + validations: + required: true + - type: textarea + id: reproduce + attributes: + label: Steps to reproduce + validations: + required: true + - type: textarea + id: context + attributes: + label: Environment and context + description: Version, environment, logs, screenshots + validations: + required: false +```` + +- [ ] **Step 3: Create `ISSUE_TEMPLATE/feature.yml`** + +````yaml +name: Feature request +description: Propose a capability +labels: [enhancement] +body: + - type: textarea + id: problem + attributes: + label: Problem + description: What user problem does this solve? + validations: + required: true + - type: textarea + id: proposal + attributes: + label: Proposal + description: What should change? + validations: + required: true + - type: textarea + id: alternatives + attributes: + label: Alternatives considered + validations: + required: false +```` + +- [ ] **Step 4: Create `ISSUE_TEMPLATE/config.yml`** + +````yaml +blank_issues_enabled: false +contact_links: + - name: Security report + url: https://github.com/Ownima/.github/security/advisories/new + about: Report a vulnerability privately + - name: Support + url: https://github.com/Ownima/.github/blob/main/SUPPORT.md + about: Where to ask for help +```` + +- [ ] **Step 5: Create `PULL_REQUEST_TEMPLATE.md`** + +````markdown +## What + + + +## Verification + +- [ ] Tests, lint and typecheck run for the touched repository +- [ ] UI change applied to every surface of the entity +- [ ] Cross-repository references are full URLs + +## Notes + + +```` + +- [ ] **Step 6: Replace `.gitignore` with a minimal one** + +```gitignore +.DS_Store +Thumbs.db +*.swp +.idea/ +.vscode/ +``` + +- [ ] **Step 7: Verify structure** + +Run: `ls CODE_OF_CONDUCT.md PULL_REQUEST_TEMPLATE.md ISSUE_TEMPLATE/bug.yml ISSUE_TEMPLATE/feature.yml ISSUE_TEMPLATE/config.yml` +Expected: all five paths listed. + +Run: `rg -n "INSERT CONTACT METHOD|TBD|TODO" CODE_OF_CONDUCT.md SECURITY.md SUPPORT.md CONTRIBUTING.md` +Expected: no output. + +- [ ] **Step 8: Commit** + +```bash +git add CODE_OF_CONDUCT.md ISSUE_TEMPLATE PULL_REQUEST_TEMPLATE.md .gitignore +git commit -m "docs: add community health files and templates" +``` + +--- + +### Task 5: Add the profile guard + +**Files:** +- Create: `scripts/check-profile-links.sh` +- Create: `.github/workflows/profile-links.yml` + +- [ ] **Step 1: Create `scripts/check-profile-links.sh`** + +```bash +#!/usr/bin/env bash +# Checks profile/README.md: repository links resolve, live domains answer, +# every non-archived org repository is mentioned. +# +# Usage: check-profile-links.sh [--strict] +# --strict a repository link that cannot be resolved is a failure +# (default: warn, because anonymous callers cannot see private repos) +set -uo pipefail +export PATH="/usr/bin:/bin:$PATH" + +ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +README="$ROOT/profile/README.md" +STRICT=0 +[ "${1:-}" = "--strict" ] && STRICT=1 + +[ -f "$README" ] || { echo "missing $README" >&2; exit 2; } + +fail=0 +warn=0 +ok=0 + +echo "== repository links ==" +for name in $(grep -oE 'https://github\.com/Ownima/[A-Za-z0-9._-]+' "$README" | sed 's#.*/##' | sort -u); do + if gh api "repos/Ownima/$name" >/dev/null 2>&1; then + echo " ok $name" + ok=$((ok + 1)) + elif [ "$STRICT" -eq 1 ]; then + echo " FAIL $name does not resolve" + fail=$((fail + 1)) + else + echo " warn $name not visible to this token" + warn=$((warn + 1)) + fi +done + +echo "== live domains ==" +for url in $(grep -oE 'https://[a-z0-9.-]+\.ownima\.com' "$README" | sort -u); do + code="$(curl -sI -o /dev/null -w '%{http_code}' --max-time 20 "$url")" || code=000 + case "$code" in + 2*|3*) echo " ok $url $code"; ok=$((ok + 1)) ;; + *) echo " FAIL $url $code"; fail=$((fail + 1)) ;; + esac +done + +echo "== coverage ==" +listed="$(grep -oE 'https://github\.com/Ownima/[A-Za-z0-9._-]+' "$README" | sed 's#.*/##' | sort -u)" +for name in $(gh repo list Ownima --limit 100 --json name,isArchived \ + --jq '.[] | select(.isArchived == false) | .name' 2>/dev/null | sort); do + [ "$name" = ".github" ] && continue + if printf '%s\n' "$listed" | grep -qx "$name"; then + echo " ok $name" + ok=$((ok + 1)) + else + echo " FAIL $name is not mentioned in profile/README.md" + fail=$((fail + 1)) + fi +done + +echo +echo "ok=$ok warn=$warn fail=$fail" +[ "$fail" -eq 0 ] +``` + +- [ ] **Step 2: Make it executable and run it locally** + +```bash +chmod +x scripts/check-profile-links.sh +scripts/check-profile-links.sh +``` + +Expected: exit 0, `fail=0`. + +- [ ] **Step 3: Create `.github/workflows/profile-links.yml`** + +```yaml +name: profile-links + +on: + pull_request: + push: + branches: [main] + schedule: + - cron: "0 6 * * 1" + workflow_dispatch: + +permissions: + contents: read + +jobs: + check: + runs-on: [self-hosted, ci] + steps: + - uses: actions/checkout@v4 + + - name: Detect app credentials + id: creds + env: + APP_ID: ${{ secrets.OWNIMA_BOT_APP_ID }} + APP_KEY: ${{ secrets.OWNIMA_BOT_PRIVATE_KEY }} + run: | + if [ -n "$APP_ID" ] && [ -n "$APP_KEY" ]; then + echo "mode=app" >> "$GITHUB_OUTPUT" + else + echo "mode=soft" >> "$GITHUB_OUTPUT" + fi + + - name: Create app token + id: app + if: steps.creds.outputs.mode == 'app' + uses: actions/create-github-app-token@v2 + with: + app-id: ${{ secrets.OWNIMA_BOT_APP_ID }} + private-key: ${{ secrets.OWNIMA_BOT_PRIVATE_KEY }} + owner: ${{ github.repository_owner }} + + - name: Check profile links + env: + GH_TOKEN: ${{ steps.app.outputs.token || github.token }} + run: | + if [ "${{ steps.creds.outputs.mode }}" = "app" ]; then + scripts/check-profile-links.sh --strict + else + echo "App credentials missing; private repository links are a warning" + scripts/check-profile-links.sh + fi +``` + +- [ ] **Step 4: Lint the workflow and script** + +Run: `bash -n scripts/check-profile-links.sh` +Expected: no output, exit 0. + +- [ ] **Step 5: Commit** + +```bash +git add scripts/check-profile-links.sh .github/workflows/profile-links.yml +git commit -m "ci: guard profile links, domains and repository coverage" +``` + +--- + +### Task 6: Apply GitHub settings + +**Files:** none (remote settings only). + +- [ ] **Step 1: Set organization profile fields** + +```bash +gh api -X PATCH orgs/Ownima \ + -f description="Vehicle rental management platform for owners and riders." \ + -f blog="https://ownima.com" \ + -f email="contact@ownima.com" +``` + +- [ ] **Step 2: Add the repository to the `ci` runner group and enable advisories** + +```bash +REPO_ID="$(gh api repos/Ownima/.github --jq .id)" +gh api -X PUT "orgs/Ownima/actions/runner-groups/6/repositories/$REPO_ID" +gh api -X PUT "repos/Ownima/.github/private-vulnerability-reporting" || \ + echo "private vulnerability reporting not available for .github" +``` + +- [ ] **Step 3: Set descriptions, homepages and topics** + +```bash +topics_json() { + python3 -c 'import json,sys; print(json.dumps({"names": sys.argv[1].split(",")}))' "$1" +} + +set_meta() { + gh api -X PATCH "repos/Ownima/$1" -f description="$2" -f homepage="$3" >/dev/null + gh api -X PUT "repos/Ownima/$1/topics" --input - <<< "$(topics_json "$4")" >/dev/null + echo "updated $1" +} + +set_meta owner-api \ + "Ownima backend: REST API, SAQ workers, Telegram bot, protobuf schema" \ + "" "python,fastapi,postgresql,opensearch,saq" +set_meta owner-web \ + "Owner dashboard: fleet, reservations, finance, Capacitor mobile" \ + "https://beta.ownima.com" "react,typescript,capacitor,tanstack,tailwindcss" +set_meta owner-admin \ + "Internal admin panel: users, operations, analytics" \ + "https://admin.ownima.com" "react,typescript,vitest,tailwindcss" +set_meta booking-web \ + "Rider-facing booking storefront for a single owner" \ + "https://booking.ownima.com" "nuxt,vue,typescript,tailwindcss" +set_meta rider-app \ + "Multi-owner rental marketplace for riders" \ + "https://rider.ownima.com" "nuxt,vue,typescript,marketplace" +set_meta ownima-blog \ + "Astro SEO site for the Ownima Thailand market" \ + "" "astro,typescript,seo" +set_meta pricing-oracle \ + "Rental pricing market intelligence over REST, A2A and Fetch.ai uAgent" \ + "" "python,fastapi,a2a,fetch-ai" +set_meta support-agent \ + "AI support agent: knowledge base, n8n workflows and evals" \ + "" "python,n8n,anthropic,evals" +set_meta ansible \ + "Ownima infrastructure: deploy playbooks, monitoring, runbooks" \ + "" "ansible,docker,monitoring,prometheus" +set_meta ownima-workspace \ + "Workspace guide and shared agent skills" \ + "" "agents,developer-experience" +set_meta .github \ + "Org profile, release guide and community health files" \ + "" "github-profile,documentation" +``` + +Each `set_meta` call outbound request is idempotent: re-running overwrites the +same values. + +- [ ] **Step 4: Verify settings** + +```bash +gh api orgs/Ownima --jq '{description,blog,email}' +for r in owner-api owner-web owner-admin booking-web rider-app ownima-blog \ + pricing-oracle support-agent ansible ownima-workspace .github; do + gh api "repos/Ownima/$r" --jq '[.name, .description, .homepage, (.topics|join(" "))] | @tsv' +done +``` + +Expected: no empty descriptions, `rider-app` homepage is `https://rider.ownima.com`, `ansible` has no typo, each repo has topics. + +--- + +### Task 7: Verify and open the PR + +**Files:** +- Create: PR body only. + +- [ ] **Step 1: Run the guard and the stale-name check** + +```bash +scripts/check-profile-links.sh +rg -n "rider-web|ownima-admin|app\.ownima\.com|stage\.ownima\.com|React 18|deplyment" profile README.md RELEASING.md +test "$(grep -oE 'https://github\.com/Ownima/[A-Za-z0-9._-]+' profile/README.md \ + | sed 's#.*/##' | grep -vE '^\.github$' | sort -u | wc -l)" -eq 10 +``` + +Expected: guard exits 0; `rg` prints nothing; the last command exits 0 with +ten distinct product/service repositories. + +- [ ] **Step 2: Check community health** + +Run: `gh api repos/Ownima/.github/community/profile --jq '{health_percentage, files: (.files | keys)}'` +Expected: `health_percentage` above 80 and the new file keys present. + +- [ ] **Step 3: Push and open the PR** + +```bash +git push -u origin docs/org-profile-refresh +gh pr create \ + --title "docs: refresh the org profile and add community health files" \ + --body "$(cat <<'EOF' +## What + +- Rewrite `profile/README.md` around live products, all ten product/service + repositories, the real stack and an agent entry point. +- Refresh `README.md` and `RELEASING.md` (four Release Please repos, correct + force-version guidance, Vercel note). +- Add SECURITY, SUPPORT, CONTRIBUTING, CODE_OF_CONDUCT, issue/PR templates and + a minimal `.gitignore`. +- Add a `profile-links` workflow that checks repository links, live domains and + repository coverage on PR, push and weekly. +- Apply organization and repository metadata with `gh` (description, website, + email, descriptions, homepages, topics) and add `.github` to the `ci` runner + group. + +## Why + +The profile was written before the 2026-08-28 renames and missed rider-app, +support-agent, pricing-oracle, ownima-blog and the workspace. It linked to a +repository that no longer exists. Community health was 37%. + +## Tests + +- `scripts/check-profile-links.sh` — exit 0. +- `rg` for stale names — no matches. +- `gh api repos/Ownima/.github/community/profile` — health above 80%. +- `profile-links` workflow green on this PR. + +Assisted-by: opencode/deepseek-v4.1-flash-free +EOF +)" +``` + +- [ ] **Step 4: Watch CI** + +Run: `gh pr checks --watch --fail-fast` +Expected: `profile-links` passes. + +- [ ] **Step 5: Report the PR URL and stop for review** + +Do not merge. The user merges manually ("Мерджим"). From 00c5a91a4cc20779a8ea2711644bfaabf8b03567 Mon Sep 17 00:00:00 2001 From: zaebee Date: Mon, 19 Oct 2026 23:05:19 +0300 Subject: [PATCH 03/17] docs(profile): refresh products, repositories and team --- profile/README.md | 99 ++++++++++++++++++++++++++++++----------------- 1 file changed, 63 insertions(+), 36 deletions(-) diff --git a/profile/README.md b/profile/README.md index 599438f..f0cd7db 100644 --- a/profile/README.md +++ b/profile/README.md @@ -1,68 +1,95 @@ # Ownima — Vehicle Rental Management Platform -**Empowering rental businesses through modern, scalable technology.** +**One platform for rental businesses and their riders: fleet, reservations, pricing and finance.** --- -## What We Build +## Live products -Ownima is a full-stack vehicle rental platform connecting rental businesses with their customers: +| Product | URL | Audience | +|---|---|---| +| Ownima | [ownima.com](https://ownima.com) | Public site | +| Rider marketplace | [rider.ownima.com](https://rider.ownima.com) | Riders across all owners | +| Booking storefront | [booking.ownima.com](https://booking.ownima.com) | Riders of one owner | +| Owner cabinet | [beta.ownima.com](https://beta.ownima.com) | Rental owners | +| Admin panel | [admin.ownima.com](https://admin.ownima.com) | Ownima operators | -| Product | Description | Stack | -|---------|-------------|-------| -| [**Owner API**](https://github.com/Ownima/owner-api) | Backend powering all business logic, REST API, background workers | Python · FastAPI · PostgreSQL · OpenSearch | -| [**Owner Web**](https://github.com/Ownima/owner-web) | Owner dashboard — fleet management, reservations, finance | React 18 · TypeScript · Capacitor (mobile) | -| [**Rider Web**](https://github.com/Ownima/rider-web) | Customer-facing app — vehicle browsing, booking, multilingual | Vue 3 · TypeScript · i18n (EN/RU/TH/VI/ID) | -| [**Admin Panel**](https://github.com/Ownima/ownima-admin) | Internal admin — analytics, user management, operations | React 19 · TypeScript | +--- + +## Platform + +- Three roles: owner, rider, admin, with role-based access control. +- Fleet and vehicle management, images stored in MinIO. +- Reservations with real-time availability and a booking request flow. +- Pricing templates (seasonal, duration-based) and a market pricing oracle. +- Wallet, transactions and financial dashboards. +- Five locales: English, Russian, Thai, Indonesian, Vietnamese. +- Background jobs on a SAQ worker queue. +- AI support drafting and vehicle image recognition. --- -## Infrastructure +## Repositories -``` -PostgreSQL — transactional data (users, wallets, transactions) -OpenSearch — vehicle/reservation documents + event log -Redis — background job queue (SAQ) + metrics cache -MinIO — vehicle images and file uploads -``` +Product repositories are private; links work for Ownima members. -Deployed via **Docker + Ansible**. CI/CD on **GitHub Actions**. Releases automated with **Release Please**. +| Repository | Role | Stack | +|---|---|---| +| [owner-api](https://github.com/Ownima/owner-api) `(private)` | REST API, workers, Telegram bot, protobuf schema | Python 3.12 · FastAPI · PostgreSQL · OpenSearch · Redis · MinIO · SAQ | +| [owner-web](https://github.com/Ownima/owner-web) `(private)` | Owner dashboard, Capacitor mobile app | React 19 · TypeScript · TanStack · Tailwind 4 · Vite · bun | +| [owner-admin](https://github.com/Ownima/owner-admin) `(private)` | Internal admin panel | React 19 · TanStack Query · Radix · Tailwind 4 · Vitest · bun | +| [booking-web](https://github.com/Ownima/booking-web) `(private)` | Rider storefront for a single owner, embeddable widget | Nuxt 4 · Vue 3 · Pinia · TanStack Vue Query · Tailwind 4 · bun | +| [rider-app](https://github.com/Ownima/rider-app) `(private)` | Multi-owner rental marketplace | Nuxt 4 · Vue 3 · FSD · Pinia · Tailwind 4 · Vercel | +| [support-agent](https://github.com/Ownima/support-agent) `(private)` | AI support drafting, knowledge base, evals | Python 3.12 · Claude · n8n | +| [pricing-oracle](https://github.com/Ownima/pricing-oracle) | Rental pricing market intelligence | Python 3.12 · FastAPI · SQLModel · A2A · Fetch.ai | +| [ownima-blog](https://github.com/Ownima/ownima-blog) `(private)` | SEO site for the Thailand market | Astro 6 · TypeScript · pagefind · bun | +| [ansible](https://github.com/Ownima/ansible) `(private)` | Infrastructure, deployment, monitoring, runbooks | Ansible · Docker · Prometheus · Grafana · Loki | +| [ownima-workspace](https://github.com/Ownima/ownima-workspace) `(private)` | Workspace guide and shared agent skills | Bash · Markdown | --- -## Key Features - -- Multi-language support: English, Russian, Thai, Vietnamese, Indonesian -- Role-based access control (Owner / Rider / Admin) -- Flexible pricing templates (seasonal, duration-based) -- Real-time availability and reservation management -- Financial dashboards, wallet system, transaction history -- Web + native mobile (iOS/Android via Capacitor) -- Background processing via SAQ worker queue -- MCP server for vehicle image recognition +## Architecture + +```mermaid +flowchart LR + RA[rider-app] --> API[owner-api] + BW[booking-web] --> API + OW[owner-web] --> API + AD[owner-admin] --> API + API --> PG[(PostgreSQL)] + API --> OS[(OpenSearch)] + API --> RD[(Redis / SAQ)] + API --> MI[(MinIO)] + API --> REC[Recognition] + SA[support-agent] --> N8N[n8n] + PO[pricing-oracle] --> API +``` --- -## Development +## For AI agents -Each repo has a `CLAUDE.md` with detailed development guidance. Quick links: +Start at [ownima-workspace](https://github.com/Ownima/ownima-workspace): it holds the +workspace guide and the shared skills. Each repository has an `AGENTS.md` with its own +commands and rules. `CLAUDE.md` only imports `AGENTS.md`. + +--- -- **Backend**: `cd owner-api/ownima-backend && docker compose watch` -- **Owner Web**: `cd owner-web && bun dev` -- **Rider Web**: `cd rider-web && bun dev` +## Releasing -See [RELEASING.md](../RELEASING.md) for the release process and conventional commit conventions. +Release Please derives versions from conventional commits. See [RELEASING.md](../RELEASING.md). --- ## Team | Role | GitHub | -|------|--------| +|---|---| | Backend / Architecture | [@zaebee](https://github.com/zaebee) | | Product / QA | [@ownima-ivan](https://github.com/ownima-ivan) | -| Frontend | [@AlexandrovTLG](https://github.com/AlexandrovTLG) · [@ReD1KC](https://github.com/ReD1KC) | +| Frontend | [@ReD1KC](https://github.com/ReD1KC) | --- -🌐 [beta.ownima.com](https://beta.ownima.com) · 📧 support@ownima.com +Contact: **contact@ownima.com** +Security: [private advisories](https://github.com/Ownima/.github/security/advisories/new) From f9ab2180937e5ff8c0cfe02dd0ab028d4656e158 Mon Sep 17 00:00:00 2001 From: zaebee Date: Mon, 19 Oct 2026 23:16:48 +0300 Subject: [PATCH 04/17] docs(profile): correct privacy and agent claims --- profile/README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/profile/README.md b/profile/README.md index f0cd7db..3c5279a 100644 --- a/profile/README.md +++ b/profile/README.md @@ -23,7 +23,7 @@ - Reservations with real-time availability and a booking request flow. - Pricing templates (seasonal, duration-based) and a market pricing oracle. - Wallet, transactions and financial dashboards. -- Five locales: English, Russian, Thai, Indonesian, Vietnamese. +- Five locales in the rider apps: English, Russian, Thai, Indonesian, Vietnamese. - Background jobs on a SAQ worker queue. - AI support drafting and vehicle image recognition. @@ -31,7 +31,7 @@ ## Repositories -Product repositories are private; links work for Ownima members. +Most product repositories are private; `pricing-oracle` is public. Links work for Ownima members. | Repository | Role | Stack | |---|---|---| @@ -70,8 +70,8 @@ flowchart LR ## For AI agents Start at [ownima-workspace](https://github.com/Ownima/ownima-workspace): it holds the -workspace guide and the shared skills. Each repository has an `AGENTS.md` with its own -commands and rules. `CLAUDE.md` only imports `AGENTS.md`. +workspace guide and the shared skills. Many repositories carry their own `AGENTS.md` or +`CLAUDE.md` with commands and rules; the workspace guide is the source of truth. --- From d7a43521fbc901425356660f263fb0bed3279071 Mon Sep 17 00:00:00 2001 From: zaebee Date: Mon, 19 Oct 2026 23:32:19 +0300 Subject: [PATCH 05/17] docs: refresh repo readme and releasing guide --- README.md | 20 ++++++++++++++++---- RELEASING.md | 43 ++++++++++++++++++++++++++----------------- 2 files changed, 42 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index a99831c..f8b6158 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,24 @@ # Ownima/.github -Org-wide defaults and documentation for the [Ownima](https://github.com/Ownima) GitHub organization. +Org-wide defaults and documentation for the [Ownima](https://github.com/Ownima) +GitHub organization. ## Contents -- [`profile/README.md`](profile/README.md) — Organization profile shown on [github.com/Ownima](https://github.com/Ownima) -- [`RELEASING.md`](RELEASING.md) — Release process, Release Please setup, conventional commit guide +- [`profile/README.md`](profile/README.md) — organization profile shown on + [github.com/Ownima](https://github.com/Ownima) +- [`RELEASING.md`](RELEASING.md) — release process and conventional commit guide +- [`CONTRIBUTING.md`](CONTRIBUTING.md) — branches, commits and PR rules +- [`SECURITY.md`](SECURITY.md) — how to report a vulnerability +- [`SUPPORT.md`](SUPPORT.md) — where to ask for help +- [`CODE_OF_CONDUCT.md`](CODE_OF_CONDUCT.md) — expected behavior + +## Changing the profile + +Open a pull request against `main`. The `profile-links` workflow checks repository +links, live domains and repository coverage on every PR and once a week. ## Issues -Cross-repo and backlog tasks are tracked here as [GitHub Issues](https://github.com/Ownima/.github/issues). +Cross-repo and backlog tasks are tracked here as +[GitHub Issues](https://github.com/Ownima/.github/issues). diff --git a/RELEASING.md b/RELEASING.md index 3e7c7af..400261d 100644 --- a/RELEASING.md +++ b/RELEASING.md @@ -1,30 +1,38 @@ # Releasing -Ownima uses [Release Please](https://github.com/googleapis/release-please) to automate versioning and changelog generation across all repos. +Ownima uses [Release Please](https://github.com/googleapis/release-please) to +automate versioning and changelog generation. ## How it works -Release Please watches commits on `main` and determines the next version from **conventional commit prefixes**: +Release Please watches commits on `main` and derives the next version from +conventional commit prefixes: | Commit prefix | Version bump | Example | -|---------------|-------------|---------| +|---|---|---| | `fix: ...` | patch | `0.2.28` → `0.2.29` | | `feat: ...` | minor | `0.2.28` → `0.3.0` | -| `feat!: ...` or `BREAKING CHANGE:` in body | major | `0.2.28` → `1.0.0` | -| `chore:`, `docs:`, `refactor:`, `ci:`, etc. | none | no release PR created | +| `feat!: ...` or `BREAKING CHANGE:` in the body | major | `0.2.28` → `1.0.0` | +| `chore:`, `docs:`, `refactor:`, `ci:`, … | none | no release PR on its own | On every push to `main` it either: -1. **Creates/updates a release PR** — titled `chore(main): release X.Y.Z` with an auto-generated CHANGELOG -2. **Tags and releases** — when the release PR is merged, it creates the git tag and GitHub Release -## Repos with Release Please +1. creates or updates a release PR titled `chore(main): release X.Y.Z` with an + autogenerated changelog, or +2. tags and releases when that PR is merged. -| Repo | Config | Current version | -|------|--------|----------------| -| `owner-api` | `release-please-config.json` + `.release-please-manifest.json` | see manifest | -| `rider-web` | `release-please-config.json` + `.release-please-manifest.json` | see manifest | +## Repositories -Both use a **GitHub App token** (`OWNIMA_BOT_APP_ID` + `OWNIMA_BOT_PRIVATE_KEY`) instead of `GITHUB_TOKEN` because the org restricts PR creation for Actions. +| Repository | Versioning | +|---|---| +| `owner-api` | `release-please-config.json` + `.release-please-manifest.json` (key `ownima-backend`) | +| `owner-web` | `release-please-config.json` + `.release-please-manifest.json` | +| `booking-web` | `release-please-config.json` + `.release-please-manifest.json` | +| `rider-app` | `release-please-config.json` + `.release-please-manifest.json` | + +They use a GitHub App token (`OWNIMA_BOT_APP_ID` + `OWNIMA_BOT_PRIVATE_KEY`) +instead of `GITHUB_TOKEN`, because the organization restricts PR creation for +Actions. `rider-app` builds and deploys on Vercel from `main`. ## Workflow @@ -41,7 +49,8 @@ push to main ## Tips -- **Force a specific version**: update `.release-please-manifest.json` manually and merge to main — Release Please will pick it up on the next run -- **Skip a release**: add `Release-As: skip` to the release PR description -- **Always patch bumps**: set `"versioning-strategy": "always-bump-patch"` in `release-please-config.json` -- **Non-releasable commits** (`chore:`, `ci:`, `docs:`) do not block a release PR from accumulating — they just don't trigger one on their own +- **Force a version**: put `Release-As: X.Y.Z` as a trailer in a commit on + `main`. Release Please picks it up on the next run. +- **Hold a release**: leave the release PR open; it keeps updating. +- **Non-releasable commits** (`chore:`, `ci:`, `docs:`) do not trigger a + release PR on their own, but they do not reset one that is already open. From 5fc1b575bdcf2bf1be144a3422ffb1a3cb9c1012 Mon Sep 17 00:00:00 2001 From: zaebee Date: Mon, 19 Oct 2026 23:35:55 +0300 Subject: [PATCH 06/17] docs: add security, support and contributing guides --- CONTRIBUTING.md | 31 +++++++++++++++++++++++++++++++ SECURITY.md | 22 ++++++++++++++++++++++ SUPPORT.md | 28 ++++++++++++++++++++++++++++ 3 files changed, 81 insertions(+) create mode 100644 CONTRIBUTING.md create mode 100644 SECURITY.md create mode 100644 SUPPORT.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..57e44c3 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,31 @@ +# Contributing + +## Branches + +Use `/-`, for example `fix/1219-time-slot-parse`. The default +branch is `main` in every repository. + +## Commits + +Conventional Commits: `type(scope): subject`. Types in use: `feat`, `fix`, +`refactor`, `chore`, `ci`, `test`, `docs`, `perf`, `style`, `build`, `revert`. + +## Pull requests + +- Keep a PR to one change. +- Link the issue when one exists. +- Make CI green before asking for review: tests, lint, typecheck and build for + the repository you touched. +- A backend request from a frontend repository is an issue on + `Ownima/owner-api`, not a task file in the frontend repository. +- Cross-repository references are full URLs. + +## Types and schemas + +Frontends generate their API types from the backend OpenAPI schema. Never +hand-edit generated directories (`gen`, `gen_types`). Regenerate and commit the +snapshot instead. + +## Where to ask + +See [SUPPORT.md](SUPPORT.md). diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000..a8872a4 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,22 @@ +# Security Policy + +## Reporting a vulnerability + +Report vulnerabilities through +[GitHub private advisories](https://github.com/Ownima/.github/security/advisories/new). +If you cannot use GitHub, email **contact@ownima.com**. + +Please include: + +- affected repository and version or commit; +- steps to reproduce; +- impact you believe it has; +- any suggested fix. + +Do not open a public issue for a vulnerability. We aim to acknowledge a report +within two working days and to keep you updated until it is resolved. + +## Supported versions + +Only the latest release of each service is supported. Security fixes are applied +to `main` and released through the normal Release Please flow. diff --git a/SUPPORT.md b/SUPPORT.md new file mode 100644 index 0000000..32c452a --- /dev/null +++ b/SUPPORT.md @@ -0,0 +1,28 @@ +# Support + +## Product questions + +Email **contact@ownima.com** or reach the team in the internal chat. + +## Bugs and feature requests + +Open an issue in the repository that owns the behavior: + +| Area | Repository | +|---|---| +| API, workers, data | `Ownima/owner-api` | +| Owner dashboard | `Ownima/owner-web` | +| Internal admin panel | `Ownima/owner-admin` | +| Rider storefront | `Ownima/booking-web` | +| Rider marketplace | `Ownima/rider-app` | +| Support automation | `Ownima/support-agent` | +| Pricing oracle | `Ownima/pricing-oracle` | +| SEO site | `Ownima/ownima-blog` | +| Infrastructure and deploys | `Ownima/ansible` | +| Workspace guide and skills | `Ownima/ownima-workspace` | + +Use this repository only for cross-repo or organization-level issues. + +## Security + +See [SECURITY.md](SECURITY.md). From ec0bde0eb3f69e2bf1e3e3fd59eecd8a69b623a0 Mon Sep 17 00:00:00 2001 From: zaebee Date: Mon, 19 Oct 2026 23:38:53 +0300 Subject: [PATCH 07/17] docs: correct security and support wording --- CONTRIBUTING.md | 3 ++- SECURITY.md | 4 ++-- SUPPORT.md | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 57e44c3..06e1bd2 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -22,7 +22,8 @@ Conventional Commits: `type(scope): subject`. Types in use: `feat`, `fix`, ## Types and schemas -Frontends generate their API types from the backend OpenAPI schema. Never +Frontends generate their API types from the backend OpenAPI schema with +`bun run gen` (`owner-web`, `owner-admin`, `booking-web`, `rider-app`). Never hand-edit generated directories (`gen`, `gen_types`). Regenerate and commit the snapshot instead. diff --git a/SECURITY.md b/SECURITY.md index a8872a4..8f42e24 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -18,5 +18,5 @@ within two working days and to keep you updated until it is resolved. ## Supported versions -Only the latest release of each service is supported. Security fixes are applied -to `main` and released through the normal Release Please flow. +Only the latest release of each released service is supported. Fixes land on +`main`; where Release Please is configured, they ship in the next release. diff --git a/SUPPORT.md b/SUPPORT.md index 32c452a..d66661d 100644 --- a/SUPPORT.md +++ b/SUPPORT.md @@ -2,7 +2,7 @@ ## Product questions -Email **contact@ownima.com** or reach the team in the internal chat. +Email **contact@ownima.com**. ## Bugs and feature requests From ea909663ee07db863fc6755fcb979ee880a15b03 Mon Sep 17 00:00:00 2001 From: zaebee Date: Mon, 19 Oct 2026 23:41:03 +0300 Subject: [PATCH 08/17] docs: add community health files and templates --- .gitignore | 212 +------------------------------------ CODE_OF_CONDUCT.md | 85 +++++++++++++++ ISSUE_TEMPLATE/bug.yml | 31 ++++++ ISSUE_TEMPLATE/config.yml | 8 ++ ISSUE_TEMPLATE/feature.yml | 24 +++++ PULL_REQUEST_TEMPLATE.md | 13 +++ 6 files changed, 166 insertions(+), 207 deletions(-) create mode 100644 CODE_OF_CONDUCT.md create mode 100644 ISSUE_TEMPLATE/bug.yml create mode 100644 ISSUE_TEMPLATE/config.yml create mode 100644 ISSUE_TEMPLATE/feature.yml create mode 100644 PULL_REQUEST_TEMPLATE.md diff --git a/.gitignore b/.gitignore index b7faf40..3bd5576 100644 --- a/.gitignore +++ b/.gitignore @@ -1,207 +1,5 @@ -# Byte-compiled / optimized / DLL files -__pycache__/ -*.py[codz] -*$py.class - -# C extensions -*.so - -# Distribution / packaging -.Python -build/ -develop-eggs/ -dist/ -downloads/ -eggs/ -.eggs/ -lib/ -lib64/ -parts/ -sdist/ -var/ -wheels/ -share/python-wheels/ -*.egg-info/ -.installed.cfg -*.egg -MANIFEST - -# PyInstaller -# Usually these files are written by a python script from a template -# before PyInstaller builds the exe, so as to inject date/other infos into it. -*.manifest -*.spec - -# Installer logs -pip-log.txt -pip-delete-this-directory.txt - -# Unit test / coverage reports -htmlcov/ -.tox/ -.nox/ -.coverage -.coverage.* -.cache -nosetests.xml -coverage.xml -*.cover -*.py.cover -.hypothesis/ -.pytest_cache/ -cover/ - -# Translations -*.mo -*.pot - -# Django stuff: -*.log -local_settings.py -db.sqlite3 -db.sqlite3-journal - -# Flask stuff: -instance/ -.webassets-cache - -# Scrapy stuff: -.scrapy - -# Sphinx documentation -docs/_build/ - -# PyBuilder -.pybuilder/ -target/ - -# Jupyter Notebook -.ipynb_checkpoints - -# IPython -profile_default/ -ipython_config.py - -# pyenv -# For a library or package, you might want to ignore these files since the code is -# intended to run in multiple environments; otherwise, check them in: -# .python-version - -# pipenv -# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. -# However, in case of collaboration, if having platform-specific dependencies or dependencies -# having no cross-platform support, pipenv may install dependencies that don't work, or not -# install all needed dependencies. -#Pipfile.lock - -# UV -# Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control. -# This is especially recommended for binary packages to ensure reproducibility, and is more -# commonly ignored for libraries. -#uv.lock - -# poetry -# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. -# This is especially recommended for binary packages to ensure reproducibility, and is more -# commonly ignored for libraries. -# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control -#poetry.lock -#poetry.toml - -# pdm -# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. -# pdm recommends including project-wide configuration in pdm.toml, but excluding .pdm-python. -# https://pdm-project.org/en/latest/usage/project/#working-with-version-control -#pdm.lock -#pdm.toml -.pdm-python -.pdm-build/ - -# pixi -# Similar to Pipfile.lock, it is generally recommended to include pixi.lock in version control. -#pixi.lock -# Pixi creates a virtual environment in the .pixi directory, just like venv module creates one -# in the .venv directory. It is recommended not to include this directory in version control. -.pixi - -# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm -__pypackages__/ - -# Celery stuff -celerybeat-schedule -celerybeat.pid - -# SageMath parsed files -*.sage.py - -# Environments -.env -.envrc -.venv -env/ -venv/ -ENV/ -env.bak/ -venv.bak/ - -# Spyder project settings -.spyderproject -.spyproject - -# Rope project settings -.ropeproject - -# mkdocs documentation -/site - -# mypy -.mypy_cache/ -.dmypy.json -dmypy.json - -# Pyre type checker -.pyre/ - -# pytype static type analyzer -.pytype/ - -# Cython debug symbols -cython_debug/ - -# PyCharm -# JetBrains specific template is maintained in a separate JetBrains.gitignore that can -# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore -# and can be added to the global gitignore or merged into this file. For a more nuclear -# option (not recommended) you can uncomment the following to ignore the entire idea folder. -#.idea/ - -# Abstra -# Abstra is an AI-powered process automation framework. -# Ignore directories containing user credentials, local state, and settings. -# Learn more at https://abstra.io/docs -.abstra/ - -# Visual Studio Code -# Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore -# that can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore -# and can be added to the global gitignore or merged into this file. However, if you prefer, -# you could uncomment the following to ignore the entire vscode folder -# .vscode/ - -# Ruff stuff: -.ruff_cache/ - -# PyPI configuration file -.pypirc - -# Cursor -# Cursor is an AI-powered code editor. `.cursorignore` specifies files/directories to -# exclude from AI features like autocomplete and code analysis. Recommended for sensitive data -# refer to https://docs.cursor.com/context/ignore-files -.cursorignore -.cursorindexingignore - -# Marimo -marimo/_static/ -marimo/_lsp/ -__marimo__/ +.DS_Store +Thumbs.db +*.swp +.idea/ +.vscode/ diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..a7da18c --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,85 @@ + +# Contributor Covenant Code of Conduct + +## Our Pledge + +We as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, caste, color, religion, or sexual identity and orientation. + +We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community. + +## Our Standards + +Examples of behavior that contributes to a positive environment for our community include: + +* Demonstrating empathy and kindness toward other people +* Being respectful of differing opinions, viewpoints, and experiences +* Giving and gracefully accepting constructive feedback +* Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience +* Focusing on what is best not just for us as individuals, but for the overall community + +Examples of unacceptable behavior include: + +* The use of sexualized language or imagery, and sexual attention or advances of any kind +* Trolling, insulting or derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or email address, without their explicit permission +* Other conduct which could reasonably be considered inappropriate in a professional setting + +## Enforcement Responsibilities + +Community leaders are responsible for clarifying and enforcing our standards of acceptable behavior and will take appropriate and fair corrective action in response to any behavior that they deem inappropriate, threatening, offensive, or harmful. + +Community leaders have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, and will communicate reasons for moderation decisions when appropriate. + +## Scope + +This Code of Conduct applies within all community spaces, and also applies when an individual is officially representing the community in public spaces. Examples of representing our community include using an official e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the community leaders responsible for enforcement at contact@ownima.com. All complaints will be reviewed and investigated promptly and fairly. + +All community leaders are obligated to respect the privacy and security of the reporter of any incident. + +## Enforcement Guidelines + +Community leaders will follow these Community Impact Guidelines in determining the consequences for any action they deem in violation of this Code of Conduct: + +### 1. Correction + +**Community Impact**: Use of inappropriate language or other behavior deemed unprofessional or unwelcome in the community. + +**Consequence**: A private, written warning from community leaders, providing clarity around the nature of the violation and an explanation of why the behavior was inappropriate. A public apology may be requested. + +### 2. Warning + +**Community Impact**: A violation through a single incident or series of actions. + +**Consequence**: A warning with consequences for continued behavior. No interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, for a specified period of time. This includes avoiding interactions in community spaces as well as external channels like social media. Violating these terms may lead to a temporary or permanent ban. + +### 3. Temporary Ban + +**Community Impact**: A serious violation of community standards, including sustained inappropriate behavior. + +**Consequence**: A temporary ban from any sort of interaction or public communication with the community for a specified period of time. No public or private interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, is allowed during this period. Violating these terms may lead to a permanent ban. + +### 4. Permanent Ban + +**Community Impact**: Demonstrating a pattern of violation of community standards, including sustained inappropriate behavior, harassment of an individual, or aggression toward or disparagement of classes of individuals. + +**Consequence**: A permanent ban from any sort of public interaction within the community. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 2.1, available at [https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1]. + +Community Impact Guidelines were inspired by [Mozilla's code of conduct enforcement ladder][Mozilla CoC]. + +For answers to common questions about this code of conduct, see the FAQ at [https://www.contributor-covenant.org/faq][FAQ]. Translations are available at [https://www.contributor-covenant.org/translations][translations]. + +[homepage]: https://www.contributor-covenant.org +[v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html +[Mozilla CoC]: https://github.com/mozilla/diversity +[FAQ]: https://www.contributor-covenant.org/faq +[translations]: https://www.contributor-covenant.org/translations + diff --git a/ISSUE_TEMPLATE/bug.yml b/ISSUE_TEMPLATE/bug.yml new file mode 100644 index 0000000..4c70c88 --- /dev/null +++ b/ISSUE_TEMPLATE/bug.yml @@ -0,0 +1,31 @@ +name: Bug report +description: Something is broken +labels: [bug] +body: + - type: input + id: repository + attributes: + label: Repository + placeholder: Ownima/owner-api + validations: + required: true + - type: textarea + id: what-happened + attributes: + label: What happened + description: Observed behavior and what you expected instead + validations: + required: true + - type: textarea + id: reproduce + attributes: + label: Steps to reproduce + validations: + required: true + - type: textarea + id: context + attributes: + label: Environment and context + description: Version, environment, logs, screenshots + validations: + required: false diff --git a/ISSUE_TEMPLATE/config.yml b/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000..481f54d --- /dev/null +++ b/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,8 @@ +blank_issues_enabled: false +contact_links: + - name: Security report + url: https://github.com/Ownima/.github/security/advisories/new + about: Report a vulnerability privately + - name: Support + url: https://github.com/Ownima/.github/blob/main/SUPPORT.md + about: Where to ask for help diff --git a/ISSUE_TEMPLATE/feature.yml b/ISSUE_TEMPLATE/feature.yml new file mode 100644 index 0000000..4b0a2e9 --- /dev/null +++ b/ISSUE_TEMPLATE/feature.yml @@ -0,0 +1,24 @@ +name: Feature request +description: Propose a capability +labels: [enhancement] +body: + - type: textarea + id: problem + attributes: + label: Problem + description: What user problem does this solve? + validations: + required: true + - type: textarea + id: proposal + attributes: + label: Proposal + description: What should change? + validations: + required: true + - type: textarea + id: alternatives + attributes: + label: Alternatives considered + validations: + required: false diff --git a/PULL_REQUEST_TEMPLATE.md b/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..cb6a74f --- /dev/null +++ b/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,13 @@ +## What + + + +## Verification + +- [ ] Tests, lint and typecheck run for the touched repository +- [ ] UI change applied to every surface of the entity +- [ ] Cross-repository references are full URLs + +## Notes + + From deb781acf14e23078315789aeeb998d06f302d2c Mon Sep 17 00:00:00 2001 From: zaebee Date: Mon, 19 Oct 2026 23:52:01 +0300 Subject: [PATCH 09/17] docs: move issue templates into .github and polish templates --- {ISSUE_TEMPLATE => .github/ISSUE_TEMPLATE}/bug.yml | 0 {ISSUE_TEMPLATE => .github/ISSUE_TEMPLATE}/config.yml | 0 {ISSUE_TEMPLATE => .github/ISSUE_TEMPLATE}/feature.yml | 0 CODE_OF_CONDUCT.md | 1 - PULL_REQUEST_TEMPLATE.md | 4 ++-- 5 files changed, 2 insertions(+), 3 deletions(-) rename {ISSUE_TEMPLATE => .github/ISSUE_TEMPLATE}/bug.yml (100%) rename {ISSUE_TEMPLATE => .github/ISSUE_TEMPLATE}/config.yml (100%) rename {ISSUE_TEMPLATE => .github/ISSUE_TEMPLATE}/feature.yml (100%) diff --git a/ISSUE_TEMPLATE/bug.yml b/.github/ISSUE_TEMPLATE/bug.yml similarity index 100% rename from ISSUE_TEMPLATE/bug.yml rename to .github/ISSUE_TEMPLATE/bug.yml diff --git a/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml similarity index 100% rename from ISSUE_TEMPLATE/config.yml rename to .github/ISSUE_TEMPLATE/config.yml diff --git a/ISSUE_TEMPLATE/feature.yml b/.github/ISSUE_TEMPLATE/feature.yml similarity index 100% rename from ISSUE_TEMPLATE/feature.yml rename to .github/ISSUE_TEMPLATE/feature.yml diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index a7da18c..57967da 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -1,4 +1,3 @@ - # Contributor Covenant Code of Conduct ## Our Pledge diff --git a/PULL_REQUEST_TEMPLATE.md b/PULL_REQUEST_TEMPLATE.md index cb6a74f..92c5edf 100644 --- a/PULL_REQUEST_TEMPLATE.md +++ b/PULL_REQUEST_TEMPLATE.md @@ -4,8 +4,8 @@ ## Verification -- [ ] Tests, lint and typecheck run for the touched repository -- [ ] UI change applied to every surface of the entity +- [ ] Tests, lint, typecheck and build run for the touched repository +- [ ] UI change applied to every surface of the entity (table view, card view, detail page) - [ ] Cross-repository references are full URLs ## Notes From a0b88528c553fd76f3f1d209d30c3e503a9936af Mon Sep 17 00:00:00 2001 From: zaebee Date: Mon, 19 Oct 2026 23:55:39 +0300 Subject: [PATCH 10/17] ci: guard profile links, domains and repository coverage --- .github/workflows/profile-links.yml | 50 +++++++++++++++++++++++ scripts/check-profile-links.sh | 61 +++++++++++++++++++++++++++++ 2 files changed, 111 insertions(+) create mode 100644 .github/workflows/profile-links.yml create mode 100755 scripts/check-profile-links.sh diff --git a/.github/workflows/profile-links.yml b/.github/workflows/profile-links.yml new file mode 100644 index 0000000..f7a9800 --- /dev/null +++ b/.github/workflows/profile-links.yml @@ -0,0 +1,50 @@ +name: profile-links + +on: + pull_request: + push: + branches: [main] + schedule: + - cron: "0 6 * * 1" + workflow_dispatch: + +permissions: + contents: read + +jobs: + check: + runs-on: [self-hosted, ci] + steps: + - uses: actions/checkout@v4 + + - name: Detect app credentials + id: creds + env: + APP_ID: ${{ secrets.OWNIMA_BOT_APP_ID }} + APP_KEY: ${{ secrets.OWNIMA_BOT_PRIVATE_KEY }} + run: | + if [ -n "$APP_ID" ] && [ -n "$APP_KEY" ]; then + echo "mode=app" >> "$GITHUB_OUTPUT" + else + echo "mode=soft" >> "$GITHUB_OUTPUT" + fi + + - name: Create app token + id: app + if: steps.creds.outputs.mode == 'app' + uses: actions/create-github-app-token@v2 + with: + app-id: ${{ secrets.OWNIMA_BOT_APP_ID }} + private-key: ${{ secrets.OWNIMA_BOT_PRIVATE_KEY }} + owner: ${{ github.repository_owner }} + + - name: Check profile links + env: + GH_TOKEN: ${{ steps.app.outputs.token || github.token }} + run: | + if [ "${{ steps.creds.outputs.mode }}" = "app" ]; then + scripts/check-profile-links.sh --strict + else + echo "App credentials missing; private repository links are a warning" + scripts/check-profile-links.sh + fi diff --git a/scripts/check-profile-links.sh b/scripts/check-profile-links.sh new file mode 100755 index 0000000..486d9de --- /dev/null +++ b/scripts/check-profile-links.sh @@ -0,0 +1,61 @@ +#!/usr/bin/env bash +# Checks profile/README.md: repository links resolve, live domains answer, +# every non-archived org repository is mentioned. +# +# Usage: check-profile-links.sh [--strict] +# --strict a repository link that cannot be resolved is a failure +# (default: warn, because anonymous callers cannot see private repos) +set -uo pipefail +export PATH="/usr/bin:/bin:$PATH" + +ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +README="$ROOT/profile/README.md" +STRICT=0 +[ "${1:-}" = "--strict" ] && STRICT=1 + +[ -f "$README" ] || { echo "missing $README" >&2; exit 2; } + +fail=0 +warn=0 +ok=0 + +echo "== repository links ==" +for name in $(grep -oE 'https://github\.com/Ownima/[A-Za-z0-9._-]+' "$README" | sed 's#.*/##' | sort -u); do + if gh api "repos/Ownima/$name" >/dev/null 2>&1; then + echo " ok $name" + ok=$((ok + 1)) + elif [ "$STRICT" -eq 1 ]; then + echo " FAIL $name does not resolve" + fail=$((fail + 1)) + else + echo " warn $name not visible to this token" + warn=$((warn + 1)) + fi +done + +echo "== live domains ==" +for url in $(grep -oE 'https://[a-z0-9.-]+\.ownima\.com' "$README" | sort -u); do + code="$(curl -sI -o /dev/null -w '%{http_code}' --max-time 20 "$url")" || code=000 + case "$code" in + 2*|3*) echo " ok $url $code"; ok=$((ok + 1)) ;; + *) echo " FAIL $url $code"; fail=$((fail + 1)) ;; + esac +done + +echo "== coverage ==" +listed="$(grep -oE 'https://github\.com/Ownima/[A-Za-z0-9._-]+' "$README" | sed 's#.*/##' | sort -u)" +for name in $(gh repo list Ownima --limit 100 --json name,isArchived \ + --jq '.[] | select(.isArchived == false) | .name' 2>/dev/null | sort); do + [ "$name" = ".github" ] && continue + if printf '%s\n' "$listed" | grep -qx "$name"; then + echo " ok $name" + ok=$((ok + 1)) + else + echo " FAIL $name is not mentioned in profile/README.md" + fail=$((fail + 1)) + fi +done + +echo +echo "ok=$ok warn=$warn fail=$fail" +[ "$fail" -eq 0 ] From be1735c0ebe40e4cb096e2f43cc35d5aac648100 Mon Sep 17 00:00:00 2001 From: zaebee Date: Mon, 19 Oct 2026 23:56:14 +0300 Subject: [PATCH 11/17] ci: also check the apex ownima.com domain --- scripts/check-profile-links.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/check-profile-links.sh b/scripts/check-profile-links.sh index 486d9de..5435e8e 100755 --- a/scripts/check-profile-links.sh +++ b/scripts/check-profile-links.sh @@ -34,7 +34,7 @@ for name in $(grep -oE 'https://github\.com/Ownima/[A-Za-z0-9._-]+' "$README" | done echo "== live domains ==" -for url in $(grep -oE 'https://[a-z0-9.-]+\.ownima\.com' "$README" | sort -u); do +for url in $(grep -oE 'https://([a-z0-9-]+\.)*ownima\.com' "$README" | sort -u); do code="$(curl -sI -o /dev/null -w '%{http_code}' --max-time 20 "$url")" || code=000 case "$code" in 2*|3*) echo " ok $url $code"; ok=$((ok + 1)) ;; From 4d81d586725b90692f4c25d2a667268a39660811 Mon Sep 17 00:00:00 2001 From: zaebee Date: Tue, 20 Oct 2026 00:07:14 +0300 Subject: [PATCH 12/17] ci: run the profile guard on hosted runners and fail loudly --- .github/workflows/profile-links.yml | 11 ++++++--- scripts/check-profile-links.sh | 38 ++++++++++++++++++++--------- 2 files changed, 34 insertions(+), 15 deletions(-) diff --git a/.github/workflows/profile-links.yml b/.github/workflows/profile-links.yml index f7a9800..2e74c45 100644 --- a/.github/workflows/profile-links.yml +++ b/.github/workflows/profile-links.yml @@ -11,11 +11,16 @@ on: permissions: contents: read +concurrency: + group: profile-links-${{ github.ref }} + cancel-in-progress: true + jobs: check: - runs-on: [self-hosted, ci] + runs-on: ubuntu-latest + timeout-minutes: 5 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Detect app credentials id: creds @@ -32,7 +37,7 @@ jobs: - name: Create app token id: app if: steps.creds.outputs.mode == 'app' - uses: actions/create-github-app-token@v2 + uses: actions/create-github-app-token@64ab729a6294000f5aa4a4bc0b73d1f32bc45510 # v3.3.0 with: app-id: ${{ secrets.OWNIMA_BOT_APP_ID }} private-key: ${{ secrets.OWNIMA_BOT_PRIVATE_KEY }} diff --git a/scripts/check-profile-links.sh b/scripts/check-profile-links.sh index 5435e8e..84639b2 100755 --- a/scripts/check-profile-links.sh +++ b/scripts/check-profile-links.sh @@ -5,6 +5,10 @@ # Usage: check-profile-links.sh [--strict] # --strict a repository link that cannot be resolved is a failure # (default: warn, because anonymous callers cannot see private repos) +# +# CI runs in soft mode unless OWNIMA_BOT_APP_ID / OWNIMA_BOT_PRIVATE_KEY are +# set on the repository: without an app token, private repositories are not +# visible and the coverage check only sees public repositories. set -uo pipefail export PATH="/usr/bin:/bin:$PATH" @@ -15,13 +19,17 @@ STRICT=0 [ -f "$README" ] || { echo "missing $README" >&2; exit 2; } +for tool in gh curl; do + command -v "$tool" >/dev/null 2>&1 || { echo "missing required tool: $tool" >&2; exit 2; } +done + fail=0 warn=0 ok=0 echo "== repository links ==" for name in $(grep -oE 'https://github\.com/Ownima/[A-Za-z0-9._-]+' "$README" | sed 's#.*/##' | sort -u); do - if gh api "repos/Ownima/$name" >/dev/null 2>&1; then + if timeout 30 gh api "repos/Ownima/$name" >/dev/null 2>&1; then echo " ok $name" ok=$((ok + 1)) elif [ "$STRICT" -eq 1 ]; then @@ -44,17 +52,23 @@ done echo "== coverage ==" listed="$(grep -oE 'https://github\.com/Ownima/[A-Za-z0-9._-]+' "$README" | sed 's#.*/##' | sort -u)" -for name in $(gh repo list Ownima --limit 100 --json name,isArchived \ - --jq '.[] | select(.isArchived == false) | .name' 2>/dev/null | sort); do - [ "$name" = ".github" ] && continue - if printf '%s\n' "$listed" | grep -qx "$name"; then - echo " ok $name" - ok=$((ok + 1)) - else - echo " FAIL $name is not mentioned in profile/README.md" - fail=$((fail + 1)) - fi -done +repos="$(timeout 60 gh repo list Ownima --limit 100 --json name,isArchived \ + --jq '.[] | select(.isArchived == false) | .name' 2>/dev/null | sort)" +if [ -z "$repos" ]; then + echo " FAIL could not enumerate org repositories" + fail=$((fail + 1)) +else + for name in $repos; do + [ "$name" = ".github" ] && continue + if printf '%s\n' "$listed" | grep -qx "$name"; then + echo " ok $name" + ok=$((ok + 1)) + else + echo " FAIL $name is not mentioned in profile/README.md" + fail=$((fail + 1)) + fi + done +fi echo echo "ok=$ok warn=$warn fail=$fail" From cf0d0331b605059cb08885eebebbfa91328475a0 Mon Sep 17 00:00:00 2001 From: zaebee Date: Tue, 20 Oct 2026 10:23:18 +0300 Subject: [PATCH 13/17] docs: drop trailing blank line from code of conduct --- CODE_OF_CONDUCT.md | 1 - 1 file changed, 1 deletion(-) diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index 57967da..f3b57a0 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -81,4 +81,3 @@ For answers to common questions about this code of conduct, see the FAQ at [http [Mozilla CoC]: https://github.com/mozilla/diversity [FAQ]: https://www.contributor-covenant.org/faq [translations]: https://www.contributor-covenant.org/translations - From 6e5628f306fe82a107c5ddff65c4b6c187f01928 Mon Sep 17 00:00:00 2001 From: zaebee Date: Tue, 20 Oct 2026 10:32:43 +0300 Subject: [PATCH 14/17] ci: retry a failed domain probe before failing --- scripts/check-profile-links.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/scripts/check-profile-links.sh b/scripts/check-profile-links.sh index 84639b2..5f10212 100755 --- a/scripts/check-profile-links.sh +++ b/scripts/check-profile-links.sh @@ -44,6 +44,10 @@ done echo "== live domains ==" for url in $(grep -oE 'https://([a-z0-9-]+\.)*ownima\.com' "$README" | sort -u); do code="$(curl -sI -o /dev/null -w '%{http_code}' --max-time 20 "$url")" || code=000 + if [ "$code" = "000" ]; then + sleep 2 + code="$(curl -sI -o /dev/null -w '%{http_code}' --max-time 20 "$url")" || code=000 + fi case "$code" in 2*|3*) echo " ok $url $code"; ok=$((ok + 1)) ;; *) echo " FAIL $url $code"; fail=$((fail + 1)) ;; From fd3330bcf27da5beedf078ae24c6daa50af5f2f7 Mon Sep 17 00:00:00 2001 From: zaebee Date: Tue, 20 Oct 2026 10:47:09 +0300 Subject: [PATCH 15/17] docs: drop implementation plan and spec from the repository --- .../plans/2026-10-19-org-profile-refresh.md | 806 ------------------ .../2026-10-19-org-profile-refresh-design.md | 148 ---- 2 files changed, 954 deletions(-) delete mode 100644 docs/superpowers/plans/2026-10-19-org-profile-refresh.md delete mode 100644 docs/superpowers/specs/2026-10-19-org-profile-refresh-design.md diff --git a/docs/superpowers/plans/2026-10-19-org-profile-refresh.md b/docs/superpowers/plans/2026-10-19-org-profile-refresh.md deleted file mode 100644 index f5e4d22..0000000 --- a/docs/superpowers/plans/2026-10-19-org-profile-refresh.md +++ /dev/null @@ -1,806 +0,0 @@ -# Org Profile Refresh Implementation Plan - -> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. - -**Goal:** Make `Ownima/.github` a truthful, healthy org profile for the team and AI agents, and add a guard that catches future drift. - -**Architecture:** A layered `profile/README.md` (public products first, internal engineering map second), a refreshed `RELEASING.md`, org-wide community health files, and a small shell guard run by GitHub Actions. GitHub settings and repository metadata are applied with `gh` outside git. - -**Tech Stack:** Markdown, Bash, GitHub CLI, GitHub Actions, Mermaid. - -**Spec:** `docs/superpowers/specs/2026-10-19-org-profile-refresh-design.md` - ---- - -### Task 1: Rewrite the profile README - -**Files:** -- Modify: `profile/README.md` - -- [ ] **Step 1: Replace `profile/README.md` with the content below** - -````markdown -# Ownima — Vehicle Rental Management Platform - -**One platform for rental businesses and their riders: fleet, reservations, pricing and finance.** - ---- - -## Live products - -| Product | URL | Audience | -|---|---|---| -| Ownima | [ownima.com](https://ownima.com) | Public site | -| Rider marketplace | [rider.ownima.com](https://rider.ownima.com) | Riders across all owners | -| Booking storefront | [booking.ownima.com](https://booking.ownima.com) | Riders of one owner | -| Owner cabinet | [beta.ownima.com](https://beta.ownima.com) | Rental owners | -| Admin panel | [admin.ownima.com](https://admin.ownima.com) | Ownima operators | - ---- - -## Platform - -- Three roles: owner, rider, admin, with role-based access control. -- Fleet and vehicle management, images stored in MinIO. -- Reservations with real-time availability and a booking request flow. -- Pricing templates (seasonal, duration-based) and a market pricing oracle. -- Wallet, transactions and financial dashboards. -- Five locales: English, Russian, Thai, Indonesian, Vietnamese. -- Background jobs on a SAQ worker queue. -- AI support drafting and vehicle image recognition. - ---- - -## Repositories - -Product repositories are private; links work for Ownima members. - -| Repository | Role | Stack | -|---|---|---| -| [owner-api](https://github.com/Ownima/owner-api) `(private)` | REST API, workers, Telegram bot, protobuf schema | Python 3.12 · FastAPI · PostgreSQL · OpenSearch · Redis · MinIO · SAQ | -| [owner-web](https://github.com/Ownima/owner-web) `(private)` | Owner dashboard, Capacitor mobile app | React 19 · TypeScript · TanStack · Tailwind 4 · Vite · bun | -| [owner-admin](https://github.com/Ownima/owner-admin) `(private)` | Internal admin panel | React 19 · TanStack Query · Radix · Tailwind 4 · Vitest · bun | -| [booking-web](https://github.com/Ownima/booking-web) `(private)` | Rider storefront for a single owner, embeddable widget | Nuxt 4 · Vue 3 · Pinia · TanStack Vue Query · Tailwind 4 · bun | -| [rider-app](https://github.com/Ownima/rider-app) `(private)` | Multi-owner rental marketplace | Nuxt 4 · Vue 3 · FSD · Pinia · Tailwind 4 · Vercel | -| [support-agent](https://github.com/Ownima/support-agent) `(private)` | AI support drafting, knowledge base, evals | Python 3.12 · Claude · n8n | -| [pricing-oracle](https://github.com/Ownima/pricing-oracle) | Rental pricing market intelligence | Python 3.12 · FastAPI · SQLModel · A2A · Fetch.ai | -| [ownima-blog](https://github.com/Ownima/ownima-blog) `(private)` | SEO site for the Thailand market | Astro 6 · TypeScript · pagefind · bun | -| [ansible](https://github.com/Ownima/ansible) `(private)` | Infrastructure, deployment, monitoring, runbooks | Ansible · Docker · Prometheus · Grafana · Loki | -| [ownima-workspace](https://github.com/Ownima/ownima-workspace) `(private)` | Workspace guide and shared agent skills | Bash · Markdown | - ---- - -## Architecture - -```mermaid -flowchart LR - RA[rider-app] --> API[owner-api] - BW[booking-web] --> API - OW[owner-web] --> API - AD[owner-admin] --> API - API --> PG[(PostgreSQL)] - API --> OS[(OpenSearch)] - API --> RD[(Redis / SAQ)] - API --> MI[(MinIO)] - API --> REC[Recognition] - SA[support-agent] --> N8N[n8n] - PO[pricing-oracle] --> API -``` - ---- - -## For AI agents - -Start at [ownima-workspace](https://github.com/Ownima/ownima-workspace): it holds the -workspace guide and the shared skills. Each repository has an `AGENTS.md` with its own -commands and rules. `CLAUDE.md` only imports `AGENTS.md`. - ---- - -## Releasing - -Release Please derives versions from conventional commits. See [RELEASING.md](../RELEASING.md). - ---- - -## Team - -| Role | GitHub | -|---|---| -| Backend / Architecture | [@zaebee](https://github.com/zaebee) | -| Product / QA | [@ownima-ivan](https://github.com/ownima-ivan) | -| Frontend | [@ReD1KC](https://github.com/ReD1KC) | - ---- - -Contact: **contact@ownima.com** -Security: [private advisories](https://github.com/Ownima/.github/security/advisories/new) -```` - -- [ ] **Step 2: Verify no stale names remain** - -Run: `rg -n "rider-web|ownima-admin|app\.ownima\.com|React 18" profile/README.md` -Expected: no output. - -- [ ] **Step 3: Commit** - -```bash -git add profile/README.md -git commit -m "docs(profile): refresh products, repositories and team" -``` - ---- - -### Task 2: Refresh the root README and RELEASING - -**Files:** -- Modify: `README.md` -- Modify: `RELEASING.md` - -- [ ] **Step 1: Replace `README.md` with the content below** - -````markdown -# Ownima/.github - -Org-wide defaults and documentation for the [Ownima](https://github.com/Ownima) -GitHub organization. - -## Contents - -- [`profile/README.md`](profile/README.md) — organization profile shown on - [github.com/Ownima](https://github.com/Ownima) -- [`RELEASING.md`](RELEASING.md) — release process and conventional commit guide -- [`CONTRIBUTING.md`](CONTRIBUTING.md) — branches, commits and PR rules -- [`SECURITY.md`](SECURITY.md) — how to report a vulnerability -- [`SUPPORT.md`](SUPPORT.md) — where to ask for help -- [`CODE_OF_CONDUCT.md`](CODE_OF_CONDUCT.md) — expected behavior - -## Changing the profile - -Open a pull request against `main`. The `profile-links` workflow checks repository -links, live domains and repository coverage on every PR and once a week. - -## Issues - -Cross-repo and backlog tasks are tracked here as -[GitHub Issues](https://github.com/Ownima/.github/issues). -```` - -- [ ] **Step 2: Replace `RELEASING.md` with the content below** - -````markdown -# Releasing - -Ownima uses [Release Please](https://github.com/googleapis/release-please) to -automate versioning and changelog generation. - -## How it works - -Release Please watches commits on `main` and derives the next version from -conventional commit prefixes: - -| Commit prefix | Version bump | Example | -|---|---|---| -| `fix: ...` | patch | `0.2.28` → `0.2.29` | -| `feat: ...` | minor | `0.2.28` → `0.3.0` | -| `feat!: ...` or `BREAKING CHANGE:` in the body | major | `0.2.28` → `1.0.0` | -| `chore:`, `docs:`, `refactor:`, `ci:`, … | none | no release PR on its own | - -On every push to `main` it either: - -1. creates or updates a release PR titled `chore(main): release X.Y.Z` with an - autogenerated changelog, or -2. tags and releases when that PR is merged. - -## Repositories - -| Repository | Versioning | -|---|---| -| `owner-api` | `release-please-config.json` + `.release-please-manifest.json` (key `ownima-backend`) | -| `owner-web` | `release-please-config.json` + `.release-please-manifest.json` | -| `booking-web` | `release-please-config.json` + `.release-please-manifest.json` | -| `rider-app` | `release-please-config.json` + `.release-please-manifest.json` | - -They use a GitHub App token (`OWNIMA_BOT_APP_ID` + `OWNIMA_BOT_PRIVATE_KEY`) -instead of `GITHUB_TOKEN`, because the organization restricts PR creation for -Actions. `rider-app` builds and deploys on Vercel from `main`. - -## Workflow - -``` -push to main - └─► release-please runs - ├─ no releasable commits → nothing happens - └─ releasable commits found - ├─ release PR already open → updates it - └─ no open release PR → creates one - └─ merge release PR - └─ creates git tag + GitHub Release -``` - -## Tips - -- **Force a version**: put `Release-As: X.Y.Z` as a trailer in a commit on - `main`. Release Please picks it up on the next run. -- **Hold a release**: leave the release PR open; it keeps updating. -- **Non-releasable commits** (`chore:`, `ci:`, `docs:`) do not trigger a - release PR on their own, but they do not reset one that is already open. -```` - -- [ ] **Step 3: Verify RELEASING lists four repositories** - -Run: `rg -c "release-please-config.json" RELEASING.md` -Expected: `4` (table rows; the intro link does not match this string). - -- [ ] **Step 4: Commit** - -```bash -git add README.md RELEASING.md -git commit -m "docs: refresh repo readme and releasing guide" -``` - ---- - -### Task 3: Add security, support and contribution files - -**Files:** -- Create: `SECURITY.md` -- Create: `SUPPORT.md` -- Create: `CONTRIBUTING.md` - -- [ ] **Step 1: Create `SECURITY.md`** - -````markdown -# Security Policy - -## Reporting a vulnerability - -Report vulnerabilities through -[GitHub private advisories](https://github.com/Ownima/.github/security/advisories/new). -If you cannot use GitHub, email **contact@ownima.com**. - -Please include: - -- affected repository and version or commit; -- steps to reproduce; -- impact you believe it has; -- any suggested fix. - -Do not open a public issue for a vulnerability. We aim to acknowledge a report -within two working days and to keep you updated until it is resolved. - -## Supported versions - -Only the latest release of each service is supported. Security fixes are applied -to `main` and released through the normal Release Please flow. -```` - -- [ ] **Step 2: Create `SUPPORT.md`** - -````markdown -# Support - -## Product questions - -Email **contact@ownima.com** or reach the team in the internal chat. - -## Bugs and feature requests - -Open an issue in the repository that owns the behavior: - -| Area | Repository | -|---|---| -| API, workers, data | `Ownima/owner-api` | -| Owner dashboard | `Ownima/owner-web` | -| Internal admin panel | `Ownima/owner-admin` | -| Rider storefront | `Ownima/booking-web` | -| Rider marketplace | `Ownima/rider-app` | -| Support automation | `Ownima/support-agent` | -| Pricing oracle | `Ownima/pricing-oracle` | -| SEO site | `Ownima/ownima-blog` | -| Infrastructure and deploys | `Ownima/ansible` | -| Workspace guide and skills | `Ownima/ownima-workspace` | - -Use this repository only for cross-repo or organization-level issues. - -## Security - -See [SECURITY.md](SECURITY.md). -```` - -- [ ] **Step 3: Create `CONTRIBUTING.md`** - -````markdown -# Contributing - -## Branches - -Use `/-`, for example `fix/1219-time-slot-parse`. The default -branch is `main` in every repository. - -## Commits - -Conventional Commits: `type(scope): subject`. Types in use: `feat`, `fix`, -`refactor`, `chore`, `ci`, `test`, `docs`, `perf`, `style`, `build`, `revert`. - -## Pull requests - -- Keep a PR to one change. -- Link the issue when one exists. -- Make CI green before asking for review: tests, lint, typecheck and build for - the repository you touched. -- A backend request from a frontend repository is an issue on - `Ownima/owner-api`, not a task file in the frontend repository. -- Cross-repository references are full URLs. - -## Types and schemas - -Frontends generate their API types from the backend OpenAPI schema. Never -hand-edit generated directories (`gen`, `gen_types`). Regenerate and commit the -snapshot instead. - -## Where to ask - -See [SUPPORT.md](SUPPORT.md). -```` - -- [ ] **Step 4: Commit** - -```bash -git add SECURITY.md SUPPORT.md CONTRIBUTING.md -git commit -m "docs: add security, support and contributing guides" -``` - ---- - -### Task 4: Add conduct, templates and a minimal gitignore - -**Files:** -- Create: `CODE_OF_CONDUCT.md` -- Create: `ISSUE_TEMPLATE/bug.yml` -- Create: `ISSUE_TEMPLATE/feature.yml` -- Create: `ISSUE_TEMPLATE/config.yml` -- Create: `PULL_REQUEST_TEMPLATE.md` -- Modify: `.gitignore` - -- [ ] **Step 1: Create `CODE_OF_CONDUCT.md` from Contributor Covenant 2.1** - -Run: - -```bash -curl -fsSL https://www.contributor-covenant.org/version/2/1/code_of_conduct/code_of_conduct.md \ - -o CODE_OF_CONDUCT.md -sed -i 's/\[INSERT CONTACT METHOD\]/contact@ownima.com/g' CODE_OF_CONDUCT.md -``` - -Expected: `CODE_OF_CONDUCT.md` is present and contains `contact@ownima.com`. - -- [ ] **Step 2: Create `ISSUE_TEMPLATE/bug.yml`** - -````yaml -name: Bug report -description: Something is broken -labels: [bug] -body: - - type: input - id: repository - attributes: - label: Repository - placeholder: Ownima/owner-api - validations: - required: true - - type: textarea - id: what-happened - attributes: - label: What happened - description: Observed behavior and what you expected instead - validations: - required: true - - type: textarea - id: reproduce - attributes: - label: Steps to reproduce - validations: - required: true - - type: textarea - id: context - attributes: - label: Environment and context - description: Version, environment, logs, screenshots - validations: - required: false -```` - -- [ ] **Step 3: Create `ISSUE_TEMPLATE/feature.yml`** - -````yaml -name: Feature request -description: Propose a capability -labels: [enhancement] -body: - - type: textarea - id: problem - attributes: - label: Problem - description: What user problem does this solve? - validations: - required: true - - type: textarea - id: proposal - attributes: - label: Proposal - description: What should change? - validations: - required: true - - type: textarea - id: alternatives - attributes: - label: Alternatives considered - validations: - required: false -```` - -- [ ] **Step 4: Create `ISSUE_TEMPLATE/config.yml`** - -````yaml -blank_issues_enabled: false -contact_links: - - name: Security report - url: https://github.com/Ownima/.github/security/advisories/new - about: Report a vulnerability privately - - name: Support - url: https://github.com/Ownima/.github/blob/main/SUPPORT.md - about: Where to ask for help -```` - -- [ ] **Step 5: Create `PULL_REQUEST_TEMPLATE.md`** - -````markdown -## What - - - -## Verification - -- [ ] Tests, lint and typecheck run for the touched repository -- [ ] UI change applied to every surface of the entity -- [ ] Cross-repository references are full URLs - -## Notes - - -```` - -- [ ] **Step 6: Replace `.gitignore` with a minimal one** - -```gitignore -.DS_Store -Thumbs.db -*.swp -.idea/ -.vscode/ -``` - -- [ ] **Step 7: Verify structure** - -Run: `ls CODE_OF_CONDUCT.md PULL_REQUEST_TEMPLATE.md ISSUE_TEMPLATE/bug.yml ISSUE_TEMPLATE/feature.yml ISSUE_TEMPLATE/config.yml` -Expected: all five paths listed. - -Run: `rg -n "INSERT CONTACT METHOD|TBD|TODO" CODE_OF_CONDUCT.md SECURITY.md SUPPORT.md CONTRIBUTING.md` -Expected: no output. - -- [ ] **Step 8: Commit** - -```bash -git add CODE_OF_CONDUCT.md ISSUE_TEMPLATE PULL_REQUEST_TEMPLATE.md .gitignore -git commit -m "docs: add community health files and templates" -``` - ---- - -### Task 5: Add the profile guard - -**Files:** -- Create: `scripts/check-profile-links.sh` -- Create: `.github/workflows/profile-links.yml` - -- [ ] **Step 1: Create `scripts/check-profile-links.sh`** - -```bash -#!/usr/bin/env bash -# Checks profile/README.md: repository links resolve, live domains answer, -# every non-archived org repository is mentioned. -# -# Usage: check-profile-links.sh [--strict] -# --strict a repository link that cannot be resolved is a failure -# (default: warn, because anonymous callers cannot see private repos) -set -uo pipefail -export PATH="/usr/bin:/bin:$PATH" - -ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" -README="$ROOT/profile/README.md" -STRICT=0 -[ "${1:-}" = "--strict" ] && STRICT=1 - -[ -f "$README" ] || { echo "missing $README" >&2; exit 2; } - -fail=0 -warn=0 -ok=0 - -echo "== repository links ==" -for name in $(grep -oE 'https://github\.com/Ownima/[A-Za-z0-9._-]+' "$README" | sed 's#.*/##' | sort -u); do - if gh api "repos/Ownima/$name" >/dev/null 2>&1; then - echo " ok $name" - ok=$((ok + 1)) - elif [ "$STRICT" -eq 1 ]; then - echo " FAIL $name does not resolve" - fail=$((fail + 1)) - else - echo " warn $name not visible to this token" - warn=$((warn + 1)) - fi -done - -echo "== live domains ==" -for url in $(grep -oE 'https://[a-z0-9.-]+\.ownima\.com' "$README" | sort -u); do - code="$(curl -sI -o /dev/null -w '%{http_code}' --max-time 20 "$url")" || code=000 - case "$code" in - 2*|3*) echo " ok $url $code"; ok=$((ok + 1)) ;; - *) echo " FAIL $url $code"; fail=$((fail + 1)) ;; - esac -done - -echo "== coverage ==" -listed="$(grep -oE 'https://github\.com/Ownima/[A-Za-z0-9._-]+' "$README" | sed 's#.*/##' | sort -u)" -for name in $(gh repo list Ownima --limit 100 --json name,isArchived \ - --jq '.[] | select(.isArchived == false) | .name' 2>/dev/null | sort); do - [ "$name" = ".github" ] && continue - if printf '%s\n' "$listed" | grep -qx "$name"; then - echo " ok $name" - ok=$((ok + 1)) - else - echo " FAIL $name is not mentioned in profile/README.md" - fail=$((fail + 1)) - fi -done - -echo -echo "ok=$ok warn=$warn fail=$fail" -[ "$fail" -eq 0 ] -``` - -- [ ] **Step 2: Make it executable and run it locally** - -```bash -chmod +x scripts/check-profile-links.sh -scripts/check-profile-links.sh -``` - -Expected: exit 0, `fail=0`. - -- [ ] **Step 3: Create `.github/workflows/profile-links.yml`** - -```yaml -name: profile-links - -on: - pull_request: - push: - branches: [main] - schedule: - - cron: "0 6 * * 1" - workflow_dispatch: - -permissions: - contents: read - -jobs: - check: - runs-on: [self-hosted, ci] - steps: - - uses: actions/checkout@v4 - - - name: Detect app credentials - id: creds - env: - APP_ID: ${{ secrets.OWNIMA_BOT_APP_ID }} - APP_KEY: ${{ secrets.OWNIMA_BOT_PRIVATE_KEY }} - run: | - if [ -n "$APP_ID" ] && [ -n "$APP_KEY" ]; then - echo "mode=app" >> "$GITHUB_OUTPUT" - else - echo "mode=soft" >> "$GITHUB_OUTPUT" - fi - - - name: Create app token - id: app - if: steps.creds.outputs.mode == 'app' - uses: actions/create-github-app-token@v2 - with: - app-id: ${{ secrets.OWNIMA_BOT_APP_ID }} - private-key: ${{ secrets.OWNIMA_BOT_PRIVATE_KEY }} - owner: ${{ github.repository_owner }} - - - name: Check profile links - env: - GH_TOKEN: ${{ steps.app.outputs.token || github.token }} - run: | - if [ "${{ steps.creds.outputs.mode }}" = "app" ]; then - scripts/check-profile-links.sh --strict - else - echo "App credentials missing; private repository links are a warning" - scripts/check-profile-links.sh - fi -``` - -- [ ] **Step 4: Lint the workflow and script** - -Run: `bash -n scripts/check-profile-links.sh` -Expected: no output, exit 0. - -- [ ] **Step 5: Commit** - -```bash -git add scripts/check-profile-links.sh .github/workflows/profile-links.yml -git commit -m "ci: guard profile links, domains and repository coverage" -``` - ---- - -### Task 6: Apply GitHub settings - -**Files:** none (remote settings only). - -- [ ] **Step 1: Set organization profile fields** - -```bash -gh api -X PATCH orgs/Ownima \ - -f description="Vehicle rental management platform for owners and riders." \ - -f blog="https://ownima.com" \ - -f email="contact@ownima.com" -``` - -- [ ] **Step 2: Add the repository to the `ci` runner group and enable advisories** - -```bash -REPO_ID="$(gh api repos/Ownima/.github --jq .id)" -gh api -X PUT "orgs/Ownima/actions/runner-groups/6/repositories/$REPO_ID" -gh api -X PUT "repos/Ownima/.github/private-vulnerability-reporting" || \ - echo "private vulnerability reporting not available for .github" -``` - -- [ ] **Step 3: Set descriptions, homepages and topics** - -```bash -topics_json() { - python3 -c 'import json,sys; print(json.dumps({"names": sys.argv[1].split(",")}))' "$1" -} - -set_meta() { - gh api -X PATCH "repos/Ownima/$1" -f description="$2" -f homepage="$3" >/dev/null - gh api -X PUT "repos/Ownima/$1/topics" --input - <<< "$(topics_json "$4")" >/dev/null - echo "updated $1" -} - -set_meta owner-api \ - "Ownima backend: REST API, SAQ workers, Telegram bot, protobuf schema" \ - "" "python,fastapi,postgresql,opensearch,saq" -set_meta owner-web \ - "Owner dashboard: fleet, reservations, finance, Capacitor mobile" \ - "https://beta.ownima.com" "react,typescript,capacitor,tanstack,tailwindcss" -set_meta owner-admin \ - "Internal admin panel: users, operations, analytics" \ - "https://admin.ownima.com" "react,typescript,vitest,tailwindcss" -set_meta booking-web \ - "Rider-facing booking storefront for a single owner" \ - "https://booking.ownima.com" "nuxt,vue,typescript,tailwindcss" -set_meta rider-app \ - "Multi-owner rental marketplace for riders" \ - "https://rider.ownima.com" "nuxt,vue,typescript,marketplace" -set_meta ownima-blog \ - "Astro SEO site for the Ownima Thailand market" \ - "" "astro,typescript,seo" -set_meta pricing-oracle \ - "Rental pricing market intelligence over REST, A2A and Fetch.ai uAgent" \ - "" "python,fastapi,a2a,fetch-ai" -set_meta support-agent \ - "AI support agent: knowledge base, n8n workflows and evals" \ - "" "python,n8n,anthropic,evals" -set_meta ansible \ - "Ownima infrastructure: deploy playbooks, monitoring, runbooks" \ - "" "ansible,docker,monitoring,prometheus" -set_meta ownima-workspace \ - "Workspace guide and shared agent skills" \ - "" "agents,developer-experience" -set_meta .github \ - "Org profile, release guide and community health files" \ - "" "github-profile,documentation" -``` - -Each `set_meta` call outbound request is idempotent: re-running overwrites the -same values. - -- [ ] **Step 4: Verify settings** - -```bash -gh api orgs/Ownima --jq '{description,blog,email}' -for r in owner-api owner-web owner-admin booking-web rider-app ownima-blog \ - pricing-oracle support-agent ansible ownima-workspace .github; do - gh api "repos/Ownima/$r" --jq '[.name, .description, .homepage, (.topics|join(" "))] | @tsv' -done -``` - -Expected: no empty descriptions, `rider-app` homepage is `https://rider.ownima.com`, `ansible` has no typo, each repo has topics. - ---- - -### Task 7: Verify and open the PR - -**Files:** -- Create: PR body only. - -- [ ] **Step 1: Run the guard and the stale-name check** - -```bash -scripts/check-profile-links.sh -rg -n "rider-web|ownima-admin|app\.ownima\.com|stage\.ownima\.com|React 18|deplyment" profile README.md RELEASING.md -test "$(grep -oE 'https://github\.com/Ownima/[A-Za-z0-9._-]+' profile/README.md \ - | sed 's#.*/##' | grep -vE '^\.github$' | sort -u | wc -l)" -eq 10 -``` - -Expected: guard exits 0; `rg` prints nothing; the last command exits 0 with -ten distinct product/service repositories. - -- [ ] **Step 2: Check community health** - -Run: `gh api repos/Ownima/.github/community/profile --jq '{health_percentage, files: (.files | keys)}'` -Expected: `health_percentage` above 80 and the new file keys present. - -- [ ] **Step 3: Push and open the PR** - -```bash -git push -u origin docs/org-profile-refresh -gh pr create \ - --title "docs: refresh the org profile and add community health files" \ - --body "$(cat <<'EOF' -## What - -- Rewrite `profile/README.md` around live products, all ten product/service - repositories, the real stack and an agent entry point. -- Refresh `README.md` and `RELEASING.md` (four Release Please repos, correct - force-version guidance, Vercel note). -- Add SECURITY, SUPPORT, CONTRIBUTING, CODE_OF_CONDUCT, issue/PR templates and - a minimal `.gitignore`. -- Add a `profile-links` workflow that checks repository links, live domains and - repository coverage on PR, push and weekly. -- Apply organization and repository metadata with `gh` (description, website, - email, descriptions, homepages, topics) and add `.github` to the `ci` runner - group. - -## Why - -The profile was written before the 2026-08-28 renames and missed rider-app, -support-agent, pricing-oracle, ownima-blog and the workspace. It linked to a -repository that no longer exists. Community health was 37%. - -## Tests - -- `scripts/check-profile-links.sh` — exit 0. -- `rg` for stale names — no matches. -- `gh api repos/Ownima/.github/community/profile` — health above 80%. -- `profile-links` workflow green on this PR. - -Assisted-by: opencode/deepseek-v4.1-flash-free -EOF -)" -``` - -- [ ] **Step 4: Watch CI** - -Run: `gh pr checks --watch --fail-fast` -Expected: `profile-links` passes. - -- [ ] **Step 5: Report the PR URL and stop for review** - -Do not merge. The user merges manually ("Мерджим"). diff --git a/docs/superpowers/specs/2026-10-19-org-profile-refresh-design.md b/docs/superpowers/specs/2026-10-19-org-profile-refresh-design.md deleted file mode 100644 index f8c37db..0000000 --- a/docs/superpowers/specs/2026-10-19-org-profile-refresh-design.md +++ /dev/null @@ -1,148 +0,0 @@ -# Org profile refresh — design - -Date: 2026-10-19 -Repo: `Ownima/.github` (local `org-profile/`) -Status: approved for implementation - -## Context - -`Ownima/.github` is the public org profile plus `RELEASING.md`. The profile -was last overhauled on 2026-06-10, before the 2026-08-28 renames -(`rider-web` → `booking-web`, `ownima-admin` → `owner-admin`) and before -`rider-app`, `support-agent`, `pricing-oracle`, `ownima-blog` and -`ownima-workspace` became part of the org. It now links to a non-existent -repository, misses half the product surface, and describes the React 18 / -single-Vue-app world. - -Audience: primarily the Ownima team and AI agents; secondarily external -visitors of `github.com/Ownima`. Product code is private except -`pricing-oracle` and `.github`. - -GitHub community health for the repo is 37%: no security, contribution, -support or conduct files, no issue/PR templates. - -## Goals - -- Make the profile truthful: names, links, stacks, repositories. -- Keep repository links (they are useful for members and agents) and label - private ones clearly. -- Give AI agents a single entry point. -- Raise the repository to a healthy community baseline. -- Prevent the same drift from recurring with an automated link check. - -## Non-goals - -- No code changes in product repositories. -- No repository visibility changes. -- No localization of the profile (English only). -- No stage or internal host names in the public profile. - -## Decisions - -| Question | Decision | -|---|---| -| Audience | Team and AI agents first, external visitors second | -| Private repo links | Keep, mark `(private)`, explain they work for org members | -| Scope | Docs + community files + GitHub settings | -| Team block | Keep, fix: `@zaebee`, `@ownima-ivan`, `@ReD1KC`; drop `@AlexandrovTLG` | -| Profile language | English | -| Canonical domains | `ownima.com`, `rider.ownima.com`, `booking.ownima.com`, `beta.ownima.com`, `admin.ownima.com` | -| Contacts | `contact@ownima.com`; vulnerabilities via GitHub advisories | -| `beta.ownima.com` | Replaces `app.ownima.com` in the profile | - -## Deliverables - -### 1. `profile/README.md` - -1. Ownima — one sentence. -2. Live products — the five canonical domains, no stage hosts. -3. Platform — owner/rider/admin roles, multilingual, reservations, pricing, - wallet, background jobs. -4. Repositories — table of repo, role, stack; private entries carry - `(private)`; one line explaining members-only links. -5. Architecture — compact Mermaid diagram: frontends → API → - PostgreSQL/OpenSearch/Redis/MinIO → workers; recognition, support-agent - and pricing-oracle shown separately. -6. For AI agents — entry point `Ownima/ownima-workspace`, then `AGENTS.md` - in each repository; `CLAUDE.md` only imports `AGENTS.md`. -7. Releasing — link to `RELEASING.md`. -8. Team — `@zaebee` (backend/architecture), `@ownima-ivan` (product/QA), - `@ReD1KC` (frontend). -9. Contact — `contact@ownima.com` and GitHub advisories. - -### 2. Other repository files - -| File | Change | -|---|---| -| `README.md` | Purpose, contents, how to propose changes | -| `RELEASING.md` | Four release-please repos; correct force-version guidance; App token; note that `rider-app` deploys on Vercel | -| `SECURITY.md` | Reporting via GitHub advisories and `contact@ownima.com` | -| `SUPPORT.md` | Support channels and issue routing | -| `CONTRIBUTING.md` | Branches, conventional commits, PR gates, cross-repo routing | -| `CODE_OF_CONDUCT.md` | Contributor Covenant 2.1, enforcement contact `contact@ownima.com` | -| `ISSUE_TEMPLATE/bug.yml`, `feature.yml`, `config.yml` | Org-wide issue templates | -| `PULL_REQUEST_TEMPLATE.md` | Description and verification checklist | -| `.gitignore` | Minimal, replaces the Python template | - -### 3. GitHub settings - -Organization: description `Vehicle rental management platform for owners and -riders.`, website `https://ownima.com`, email `contact@ownima.com`. - -Repository metadata (description / homepage / topics): - -| Repo | Description | Homepage | Topics | -|---|---|---|---| -| `owner-api` | Ownima backend: REST API, SAQ workers, Telegram bot, protobuf schema | — | python, fastapi, postgresql, opensearch, saq | -| `owner-web` | Owner dashboard: fleet, reservations, finance, Capacitor mobile | `https://beta.ownima.com` | react, typescript, capacitor, tanstack, tailwindcss | -| `owner-admin` | Internal admin panel: users, operations, analytics | `https://admin.ownima.com` | react, typescript, vitest, tailwindcss | -| `booking-web` | Rider-facing booking storefront for a single owner | `https://booking.ownima.com` | nuxt, vue, typescript, tailwindcss | -| `rider-app` | Multi-owner rental marketplace for riders | `https://rider.ownima.com` | nuxt, vue, typescript, marketplace | -| `ownima-blog` | Astro SEO site for the Ownima Thailand market | — | astro, typescript, seo | -| `pricing-oracle` | Rental pricing market intelligence over REST, A2A and Fetch.ai uAgent | — | python, fastapi, a2a, fetch-ai | -| `support-agent` | AI support agent: knowledge base, n8n workflows and evals | — | python, n8n, anthropic, evals | -| `ansible` | Ownima infrastructure: deploy playbooks, monitoring, runbooks | — | ansible, docker, monitoring, prometheus | -| `ownima-workspace` | Workspace guide and shared agent skills | — | agents, developer-experience | -| `.github` | Org profile, release guide and community health files | — | — | - -Enable private vulnerability reporting where available. Add the `.github` -repository to the org runner group `ci` so the guard workflow can run on the -self-hosted runner. - -### 4. Guard workflow - -`.github/workflows/profile-links.yml`, triggered on PR, push to `main` and -weekly: - -- every `github.com/Ownima/` link in `profile/README.md` resolves - (GitHub App token for private repos); -- every live domain in the profile returns 2xx; -- every non-archived org repository is mentioned in the profile. - -## Acceptance criteria - -- `profile/README.md` contains no reference to `rider-web` or `ownima-admin`. -- All five canonical domains are listed; no `*.ownima.com` stage host appears. -- Each of the ten product/service repositories (all except `.github`) - appears once in the repository table. -- `RELEASING.md` lists exactly the four release-please repositories. -- `gh api repos/Ownima/.github/community/profile` reports the new files and - a health percentage above 80%. -- Guard workflow passes on the PR and on a manual run. -- Existing `LICENSE` is unchanged. - -## Risks - -- Org settings and repository metadata are applied with `gh`; a mistake is - visible org-wide. Each change is listed in the PR body before it is applied. -- GitHub App secrets may not be available to the `.github` repository; if - they are missing, the guard falls back to public-link checking and reports - the private-repo check as skipped instead of failing. -- A Mermaid diagram renders differently across GitHub clients; it stays - small and text-readable in source. - -## Out of scope - -- Making product repositories public. -- Rewriting each repository's README. -- Adding a LICENSE to product repositories. From e724f0e032c35649754e5b0ddab816921ec5e4e9 Mon Sep 17 00:00:00 2001 From: zaebee Date: Tue, 20 Oct 2026 07:55:04 +0000 Subject: [PATCH 16/17] fix: absolute RELEASING link in the profile, probe domains with GET The org profile renders on github.com/Ownima, where a relative link does not resolve. HEAD probes fail on servers that answer HEAD with 405, and the PATH override shadowed a newer gh outside /usr/bin. Co-Authored-By: Claude Opus 5.5 --- profile/README.md | 2 +- scripts/check-profile-links.sh | 10 +++++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/profile/README.md b/profile/README.md index 3c5279a..74b4fe5 100644 --- a/profile/README.md +++ b/profile/README.md @@ -77,7 +77,7 @@ workspace guide and the shared skills. Many repositories carry their own `AGENTS ## Releasing -Release Please derives versions from conventional commits. See [RELEASING.md](../RELEASING.md). +Release Please derives versions from conventional commits. See [RELEASING.md](https://github.com/Ownima/.github/blob/main/RELEASING.md). --- diff --git a/scripts/check-profile-links.sh b/scripts/check-profile-links.sh index 5f10212..ff2491d 100755 --- a/scripts/check-profile-links.sh +++ b/scripts/check-profile-links.sh @@ -10,7 +10,6 @@ # set on the repository: without an app token, private repositories are not # visible and the coverage check only sees public repositories. set -uo pipefail -export PATH="/usr/bin:/bin:$PATH" ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" README="$ROOT/profile/README.md" @@ -23,6 +22,11 @@ for tool in gh curl; do command -v "$tool" >/dev/null 2>&1 || { echo "missing required tool: $tool" >&2; exit 2; } done +# GET of a single byte, not HEAD: some servers and CDNs answer HEAD with 405. +probe() { + curl -s -o /dev/null -r 0-0 -w '%{http_code}' --max-time 20 "$1" +} + fail=0 warn=0 ok=0 @@ -43,10 +47,10 @@ done echo "== live domains ==" for url in $(grep -oE 'https://([a-z0-9-]+\.)*ownima\.com' "$README" | sort -u); do - code="$(curl -sI -o /dev/null -w '%{http_code}' --max-time 20 "$url")" || code=000 + code="$(probe "$url")" || code=000 if [ "$code" = "000" ]; then sleep 2 - code="$(curl -sI -o /dev/null -w '%{http_code}' --max-time 20 "$url")" || code=000 + code="$(probe "$url")" || code=000 fi case "$code" in 2*|3*) echo " ok $url $code"; ok=$((ok + 1)) ;; From c6946d22667ab095164648b5ef5bbdfc71b0b990 Mon Sep 17 00:00:00 2001 From: zaebee Date: Tue, 20 Oct 2026 07:57:36 +0000 Subject: [PATCH 17/17] docs: keep the admin panel URL out of the public profile Co-Authored-By: Claude Opus 5.5 --- profile/README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/profile/README.md b/profile/README.md index 74b4fe5..a35a69e 100644 --- a/profile/README.md +++ b/profile/README.md @@ -12,7 +12,6 @@ | Rider marketplace | [rider.ownima.com](https://rider.ownima.com) | Riders across all owners | | Booking storefront | [booking.ownima.com](https://booking.ownima.com) | Riders of one owner | | Owner cabinet | [beta.ownima.com](https://beta.ownima.com) | Rental owners | -| Admin panel | [admin.ownima.com](https://admin.ownima.com) | Ownima operators | ---