# Release Checklist (বাংলা) 🌐 **Languages:** 🇺🇸 [English](../../../../ops/RELEASE_CHECKLIST.md) · 🇪🇹 [am](../../../am/docs/ops/RELEASE_CHECKLIST.md) · 🇸🇦 [ar](../../../ar/docs/ops/RELEASE_CHECKLIST.md) · 🇦🇿 [az](../../../az/docs/ops/RELEASE_CHECKLIST.md) · 🇧🇬 [bg](../../../bg/docs/ops/RELEASE_CHECKLIST.md) · 🇧🇦 [bs](../../../bs/docs/ops/RELEASE_CHECKLIST.md) · 🇨🇿 [cs](../../../cs/docs/ops/RELEASE_CHECKLIST.md) · 🇩🇰 [da](../../../da/docs/ops/RELEASE_CHECKLIST.md) · 🇩🇪 [de](../../../de/docs/ops/RELEASE_CHECKLIST.md) · 🇬🇷 [el](../../../el/docs/ops/RELEASE_CHECKLIST.md) · 🇪🇸 [es](../../../es/docs/ops/RELEASE_CHECKLIST.md) · 🇪🇪 [et](../../../et/docs/ops/RELEASE_CHECKLIST.md) · 🇮🇷 [fa](../../../fa/docs/ops/RELEASE_CHECKLIST.md) · 🇫🇮 [fi](../../../fi/docs/ops/RELEASE_CHECKLIST.md) · 🇫🇷 [fr](../../../fr/docs/ops/RELEASE_CHECKLIST.md) · 🇮🇪 [ga](../../../ga/docs/ops/RELEASE_CHECKLIST.md) · 🇮🇳 [gu](../../../gu/docs/ops/RELEASE_CHECKLIST.md) · 🇳🇬 [ha](../../../ha/docs/ops/RELEASE_CHECKLIST.md) · 🇮🇱 [he](../../../he/docs/ops/RELEASE_CHECKLIST.md) · 🇮🇳 [hi](../../../hi/docs/ops/RELEASE_CHECKLIST.md) · 🇭🇷 [hr](../../../hr/docs/ops/RELEASE_CHECKLIST.md) · 🇭🇺 [hu](../../../hu/docs/ops/RELEASE_CHECKLIST.md) · 🇦🇲 [hy](../../../hy/docs/ops/RELEASE_CHECKLIST.md) · 🇮🇩 [id](../../../id/docs/ops/RELEASE_CHECKLIST.md) · 🇳🇬 [ig](../../../ig/docs/ops/RELEASE_CHECKLIST.md) · 🇮🇹 [it](../../../it/docs/ops/RELEASE_CHECKLIST.md) · 🇯🇵 [ja](../../../ja/docs/ops/RELEASE_CHECKLIST.md) · 🇬🇪 [ka](../../../ka/docs/ops/RELEASE_CHECKLIST.md) · 🇰🇭 [km](../../../km/docs/ops/RELEASE_CHECKLIST.md) · 🇮🇳 [kn](../../../kn/docs/ops/RELEASE_CHECKLIST.md) · 🇰🇷 [ko](../../../ko/docs/ops/RELEASE_CHECKLIST.md) · 🇱🇹 [lt](../../../lt/docs/ops/RELEASE_CHECKLIST.md) · 🇱🇻 [lv](../../../lv/docs/ops/RELEASE_CHECKLIST.md) · 🇮🇳 [ml](../../../ml/docs/ops/RELEASE_CHECKLIST.md) · 🇮🇳 [mr](../../../mr/docs/ops/RELEASE_CHECKLIST.md) · 🇲🇾 [ms](../../../ms/docs/ops/RELEASE_CHECKLIST.md) · 🇲🇹 [mt](../../../mt/docs/ops/RELEASE_CHECKLIST.md) · 🇲🇲 [my](../../../my/docs/ops/RELEASE_CHECKLIST.md) · 🇳🇵 [ne](../../../ne/docs/ops/RELEASE_CHECKLIST.md) · 🇳🇱 [nl](../../../nl/docs/ops/RELEASE_CHECKLIST.md) · 🇳🇴 [no](../../../no/docs/ops/RELEASE_CHECKLIST.md) · 🇮🇳 [or](../../../or/docs/ops/RELEASE_CHECKLIST.md) · 🇮🇳 [pa](../../../pa/docs/ops/RELEASE_CHECKLIST.md) · 🇵🇭 [phi](../../../phi/docs/ops/RELEASE_CHECKLIST.md) · 🇵🇱 [pl](../../../pl/docs/ops/RELEASE_CHECKLIST.md) · 🇵🇹 [pt](../../../pt/docs/ops/RELEASE_CHECKLIST.md) · 🇧🇷 [pt-BR](../../../pt-BR/docs/ops/RELEASE_CHECKLIST.md) · 🇷🇴 [ro](../../../ro/docs/ops/RELEASE_CHECKLIST.md) · 🇷🇺 [ru](../../../ru/docs/ops/RELEASE_CHECKLIST.md) · 🇱🇰 [si](../../../si/docs/ops/RELEASE_CHECKLIST.md) · 🇸🇰 [sk](../../../sk/docs/ops/RELEASE_CHECKLIST.md) · 🇸🇮 [sl](../../../sl/docs/ops/RELEASE_CHECKLIST.md) · 🇷🇸 [sr](../../../sr/docs/ops/RELEASE_CHECKLIST.md) · 🇸🇪 [sv](../../../sv/docs/ops/RELEASE_CHECKLIST.md) · 🇰🇪 [sw](../../../sw/docs/ops/RELEASE_CHECKLIST.md) · 🇮🇳 [ta](../../../ta/docs/ops/RELEASE_CHECKLIST.md) · 🇮🇳 [te](../../../te/docs/ops/RELEASE_CHECKLIST.md) · 🇹🇭 [th](../../../th/docs/ops/RELEASE_CHECKLIST.md) · 🇹🇷 [tr](../../../tr/docs/ops/RELEASE_CHECKLIST.md) · 🇺🇦 [uk-UA](../../../uk-UA/docs/ops/RELEASE_CHECKLIST.md) · 🇵🇰 [ur](../../../ur/docs/ops/RELEASE_CHECKLIST.md) · 🇺🇿 [uz](../../../uz/docs/ops/RELEASE_CHECKLIST.md) · 🇻🇳 [vi](../../../vi/docs/ops/RELEASE_CHECKLIST.md) · 🇳🇬 [yo](../../../yo/docs/ops/RELEASE_CHECKLIST.md) · 🇨🇳 [zh-CN](../../../zh-CN/docs/ops/RELEASE_CHECKLIST.md) · 🇹🇼 [zh-TW](../../../zh-TW/docs/ops/RELEASE_CHECKLIST.md) --- > **সর্বশেষ আপডেট:** 2026-08-28 — v3.8.51 > অটোমেশনের জন্য Claude Code skills ব্যবহারকারী সরলীকৃত রিলিজ প্রক্রিয়া। > > **রিলিজগুলোর মধ্যবর্তী সময়ে queue/branch সবুজ রাখুন:** দেখুন [RELEASE_GREEN.md](./RELEASE_GREEN.md) > (`/green-prs` family + `npm run check:release-green` + `/babysit` + nightly)। এটি পর্যায়ক্রমে চালালে— > এবং বিশেষ করে এই checklist-এর **আগে** চালালে—release PR শুরু থেকেই সবুজ থাকে। ## সংক্ষেপে ```bash # ১. সংস্করণ বাড়ান + CHANGELOG তৈরি করুন (skill) /version-bump-cc patch # অথবা minor/major # ২. স্থানীয়ভাবে quality gate চালান npm run check # lint + tests npm run test:coverage # সম্পূর্ণ coverage gate (60/60/60/60) # ৩. Build ও smoke test npm run build npm run test:e2e # ঐচ্ছিক, তবে সুপারিশকৃত # ৪. রিলিজ তৈরি করুন (skill) /generate-release-cc # ৫. Deploy করুন (skill) /deploy-vps-both-cc # অথবা akamai-cc / local-cc # ৬. রিলিজের প্রমাণ সংগ্রহ করুন (skill) /capture-release-evidences-cc ``` ## npm Trusted Publishing (v3.8.51 থেকে ডিফল্ট) — অনুরোধে staged, fallback হিসেবে direct ডিফল্টভাবে `npm-publish.yml` **npm Trusted Publishing (OIDC)**-এর মাধ্যমে প্রকাশ করে: `stage-npm` job (github-hosted) ওই run-এর জন্য GitHub-এর id-token-কে স্বল্পমেয়াদি npm credential-এ বিনিময় করে—repository secrets-এ দীর্ঘমেয়াদি npm token থাকে না, কোনো 2FA prompt নেই এবং provenance সংযুক্ত থাকে। 2FA এড়িয়ে যাওয়া token-গুলো অবসরে পাঠানো হচ্ছে বলে npm বর্তমানে অনুমোদিত যে bypass ব্যবস্থা দেয়, এটি সেটিই; এটি WS1.3 নিশ্চয়তা বজায় রেখে প্রকল্পের v3.8.48 পর্যন্ত থাকা সম্পূর্ণ স্বয়ংক্রিয় প্রক্রিয়াটি পুনরুদ্ধার করে (ফাঁস হওয়া কোনো token একা publish করতে পারে না—কারণ কোনো token-ই নেই)। **এককালীন setup (owner):** npmjs.com → package `omniroute` → Settings → _Trusted Publisher_ → GitHub: owner `diegosouzapw`, repo `OmniRoute`, workflow `npm-publish.yml` (environment: none)। এটি তৈরি না হওয়া পর্যন্ত স্বয়ংক্রিয় ধাপটি `ENEEDAUTH` দিয়ে ব্যর্থ হবে: `publish_mode=staged` (নিচে) অথবা `direct` দিয়ে পুনরায় dispatch করুন। ### Staged publishing (অনুরোধে—`publish_mode=staged`) npm-publish workflow আর সরাসরি publish করে না: এটি packed tarball-টি boot করে (`check:pack-boot`) এবং তারপর `npm stage publish` চালায়—হুবহু একই bytes registry-তে সংরক্ষিত থাকে, owner অনুমোদন না করা পর্যন্ত **install করা যায় না**। মানবীয় 2FA gate-টি প্রমাণ যাচাইয়ের আগের অবস্থান থেকে পরের অবস্থানে সরানো হয়েছে। **Workflow সবুজ হওয়ার পর owner-এর প্রক্রিয়া:** 1. `npm stage list omniroute`—stage id খুঁজুন (workflow summary-তেও দেখানো হয়)। 2. staged bytes যাচাই করুন (সুপারিশকৃত): `npm stage download `, তারপর download করা tarball-টি একটি অস্থায়ী prefix-এ install করে boot করুন (`npm run check:pack-boot` CI-তে একই pack→install→boot ফলাফল স্বয়ংক্রিয়ভাবে নির্ধারণ করে)। 3. `npm stage approve `—2FA prompt-টিই হলো publish। `npm stage reject ` বাতিল করে। 4. Publish-পরবর্তী নিরাপত্তা ব্যবস্থা: post-publish verifier (v3.8.49 পরিকল্পনার WS1.4) একটি clean container-এ public registry থেকে প্রকাশিত version install করে এবং সেটি boot করে। **জরুরি fallback:** `publish_mode=direct` সহ `workflow_dispatch` পুরোনো তাৎক্ষণিক `npm publish` পুনরুদ্ধার করে (শুধু staging নিজেই ত্রুটিপূর্ণ আচরণ করলে ব্যবহার করুন; কারণটি নথিভুক্ত করুন)। **এককালীন hardening (owner, npmjs.com):** `omniroute`-এর Trusted Publisher-কে stage-only mode-এ configure করুন, যাতে ফাঁস হওয়া কোনো দীর্ঘমেয়াদি token কোথাও থেকে সরাসরি `npm publish` করতে না পারে—CI শুধু stage করতে পারবে; কেবল owner-এর 2FA-ই release করবে। **ত্রুটিপূর্ণ artifact-এর playbook (অপরিবর্তিত):** ডিফল্ট তাৎক্ষণিক ব্যবস্থা হিসেবে `npm deprecate omniroute@ " — use "` ব্যবহার করুন (কয়েক মিনিট লাগে, প্রত্যাবর্তনযোগ্য); `npm unpublish` কেবল 72h/no-dependents সীমার মধ্যে ব্যবহার করুন এবং কখনোই প্রথম পদক্ষেপ হিসেবে নয়। Docker-এর ক্ষেত্রে: কোনো version tag কখনো পুনর্লিখবেন না—rollback মানে `latest`-কে সর্বশেষ ভালো digest-এর দিকে পুনর্নির্দেশ করা। **Docker Hub `latest` (প্রতিটি stable SemVer publish-এ আবশ্যক):** `docker-publish` workflow-কে **উভয়** `X.Y.Z` এবং, `should-promote-latest.sh` যদি একমত হয় যে এটিই সর্বোচ্চ stable SemVer, একই **digest**-সহ `:latest` tag করতে হবে। Job শেষ হওয়ার পর: Hub-এর `latest` digest নতুন SemVer digest-এর সমান হবে এবং `last_updated` এগিয়ে যাবে। Release notes-এ এমন fix-এর কথা বলা হলেও যা শুধু git-এ রয়েছে, `:latest`-কে কোনো পুরোনো build-এ রেখে দেবেন না। Compose quickstart-গুলো `:latest` ব্যবহার করে; GitOps-এর ক্ষেত্রে `X.Y.Z` pin করা চালিয়ে যেতে হবে। দেখুন [Docker release channel](../guides/DOCKER_GUIDE.md#release-channels) এবং #10317। ## হটফিক্স ফাস্ট-লেন (লেবেল `hotfix`) `hotfix` লেবেলযুক্ত একটি PR ভারী CI ম্যাট্রিক্স (9-shard E2E, coverage ratchet, quality-gate, quality-extended) এড়িয়ে যায় এবং দ্রুত, উচ্চ-সংকেতসম্পন্ন গেটগুলো বজায় রাখে: build, unit shards, integration, vitest, lint/typecheck, docs-sync, `check:pack-artifact` এবং tarball boot-smoke (`check:pack-boot`)। লক্ষ্য: ~33min-এর পরিবর্তে ≤15min-এ সবুজ। **প্রবেশের নীতি — চারটিই আবশ্যক (Chromium/VS Code/Node-এর জরুরি লেন অনুসারে মডেল করা):** 1. **তীব্রতা**: প্রোডাকশন ভেঙে গেছে — প্রকাশিত artifact বুটের সময় ক্র্যাশ করে / একটি নিরাপত্তা সংশোধন / রিলিজটির প্রত্যেক ব্যবহারকারী প্রভাবিত। "গুরুত্বপূর্ণ" মানেই "ভেঙে গেছে" নয়। 2. **কর্তৃত্ব**: কেবল repository owner-ই `hotfix` লেবেল প্রয়োগ করেন। লেবেলটিই অনুমোদন — campaign PR-এ কখনোই নিজে থেকে এটি ব্যবহার করবেন না। 3. **প্রমাণ**: PR body-তে আগের সম্পূর্ণ-সবুজ heavy run-এর লিঙ্ক থাকে (যে suite-টি বাদ দেওয়া job-গুলো পুনরায় যাচাই করত), সঙ্গে fix-টির নিজস্ব আগে-ব্যর্থ-তারপর-সফল test। 4. **পরিধি**: শুধু cherry-pick — ন্যূনতম fix, কোনো refactor নয়, কোনো অপ্রাসঙ্গিক পরিবর্তন নয়। বাদ দেওয়া coverage/ratchet surface-টি release branch-এর পরবর্তী পূর্ণ run-এ পুনরায় যাচাই করা হয় (অবিচ্ছিন্ন release-green) — এই lane কেবল অপেক্ষা এড়িয়ে যায়, validation কখনো নয়। শুধু test-সংক্রান্ত diff (সব file `tests/`-এর অধীনে, কোনোটি `tests/e2e/`-এর অধীনে নয়) কোনো label ছাড়াই স্বয়ংক্রিয়ভাবে E2E matrix এড়িয়ে যায়। ## বিস্তারিত চেকলিস্ট ### রিলিজ-পূর্ব - [ ] এই রিলিজের জন্য নির্ধারিত সব PR `release/vX.Y.0`-এ merge করা হয়েছে - [ ] এই version-এর সব খোলা Linear/issue item বন্ধ করা হয়েছে অথবা পরবর্তী milestone-এ সরানো হয়েছে - [ ] `release/vX.Y.0` branch-এ CI সবুজ - [ ] code-এ কোনো `TODO(release)` marker নেই: `grep -r "TODO(release)" src/ open-sse/` - [ ] Docker base image হালনাগাদ (বর্তমানে `node:24.15.0-trixie-slim`) ### Version ও Changelog - [ ] `/version-bump-cc ` চালান (Claude Code skill) - `package.json`, `electron/package.json`-এর version বৃদ্ধি করে - সর্বশেষ tag-এর পরের git commitগুলো থেকে `CHANGELOG.md` পুনরায় তৈরি করে - README.md badgeগুলো হালনাগাদ করে - [ ] CHANGELOG.md হাতে পর্যালোচনা করুন এবং প্রয়োজন হলে commit messageগুলো পরিষ্কার করুন - [ ] নিশ্চিত করুন যে `CHANGELOG.md`-এর সর্বশেষ semver section `package.json`-এর version-এর সমান - [ ] আসন্ন কাজের জন্য `## [Unreleased]`-কে প্রথম changelog section হিসেবে রাখুন - [ ] `docs/openapi.yaml` হালনাগাদ করুন → `info.version` অবশ্যই `package.json`-এর version-এর সমান হতে হবে ### Code-এর গুণমান - [ ] `npm run lint` — 0টি error (warningগুলো আগে থেকেই ছিল) - [ ] `npm run typecheck:core` — পরিষ্কার - [ ] `npm run typecheck:noimplicit:core` — পরিষ্কার (strict) - [ ] `npm run check:cycles` — কোনো circular dependency নেই - [ ] `npm run check:any-budget:t11` — budget-এর মধ্যে - [ ] `npm run check:route-validation:t06` — পরিষ্কার - [ ] `npm run check:node-runtime` — সমর্থিত runtime-এর ন্যূনতম সীমা পূরণ হয়েছে (`>=22.22.2 <23`, `>=24.0.0 <27`, `src/shared/utils/nodeRuntimeSupport.ts`-এর `SUPPORTED_NODE_RANGE` অনুসারে; `package.json`-এর `engines`-এর সঙ্গে সামঞ্জস্যপূর্ণ) ### Testing - [ ] `npm run test:unit` — সফল - [ ] `npm run test:vitest` — সফল (MCP server, autoCombo, cache) - [ ] `npm run test:coverage` — gate 60/60/60/60 পূরণ হয়েছে (statement/line/function/branch) - [ ] `npm run test:integration` — সফল (পরিবর্তনগুলো DB / handler স্পর্শ করলে) - [ ] `npm run test:combo:matrix` — সফল (combo strategy matrix: সব 19টি public routing strategy-এর selection decision নির্ধারিতভাবে প্রমাণ করে; combo routing, strategy resolution অথবা fallback logic স্পর্শ করলে চালান) - [ ] `RUN_COMBO_LIVE=1 npm run test:combo:live` — **ঐচ্ছিক/ম্যানুয়াল** (gate-নিয়ন্ত্রিত real-upstream smoke; VPS `root@192.168.0.15` থেকে read-only DB snapshot সংগ্রহ করে; প্রকৃত provider-এ অনুরোধ পাঠায়, credit খরচ করে; CI-তে কখনো চলে না; gate না থাকলে পরিচ্ছন্নভাবে skip করে) - [ ] `npm run test:combo:live:vps` — **ঐচ্ছিক/ম্যানুয়াল** (Phase-3 VPS live smoke: সাধারণ Node ESM-এর মাধ্যমে live `.15` server-এর বিরুদ্ধে 7টি HTTP scenario; `ssh root@192.168.0.15` প্রয়োজন; শুধু `__live_test__*` combo তৈরি/মুছে দেয়; প্রকৃত provider-এ অনুরোধ পাঠায়; CI-তে কখনো চলে না) - [ ] `npm run test:e2e` — সফল (UI পরিবর্তন) - [ ] `npm run test:protocols:e2e` — সফল (MCP/A2A পরিবর্তন) - [ ] `npm run test:ecosystem` — সফল ### Hook (Husky দ্বারা যাচাইকৃত) Husky hookগুলো `.husky/`-এ থাকে এবং git operation-এর সময় স্বয়ংক্রিয়ভাবে চলে। - **pre-commit:** `npx lint-staged + node scripts/check/check-docs-sync.mjs + npm run check:any-budget:t11` - **pre-push:** দ্রুত ও নির্ধারিত gate — `npm run check:any-budget:t11 && npm run check:tracked-artifacts` (2026-06-13-এ সক্রিয় করা হয়েছে)। ইচ্ছাকৃতভাবে `test:unit` বাদ দেয় (ধীর; CI-এর `test-unit` job দ্বারা অন্তর্ভুক্ত)। - release branch push করার আগে হাতে `npm run test:unit` চালান। কোনো hook ব্যর্থ হলে: মূল সমস্যাটি ঠিক করুন, `--no-verify` দিয়ে এড়িয়ে যাবেন না। ### Conventional Commit রিলিজে অন্তর্ভুক্ত সব commit-কে অবশ্যই `type(scope): subject` format অনুসরণ করতে হবে। **বৈধ type:** `feat`, `fix`, `refactor`, `docs`, `test`, `chore`, `perf`, `style`, `ci` **বৈধ scope:** `db`, `sse`, `oauth`, `dashboard`, `api`, `cli`, `docker`, `ci`, `mcp`, `a2a`, `memory`, `skills`, `cloud-agent`, `guardrails`, `compression`, `auto-combo`, `resilience`, `providers`, `executors`, `translator`, `domain`, `authz` Breaking change: `BREAKING CHANGE:` footer যোগ করুন অথবা scope-এর পরে `!` যোগ করুন (যেমন `feat(api)!: drop /v0`)। ### ডকুমেন্টেশন - [ ] `npm run check:docs-sync` সফল হয় (pre-commit দ্বারা স্বয়ংক্রিয়ভাবে চালানো হয়) - [ ] `npm run check:docs-all` সফল হয় (সমন্বিত পরীক্ষা: docs-sync + docs-counts + env-doc-sync + deprecated-versions + doc-links) - [ ] `npm run check:env-doc-sync` 0 কোডসহ সমাপ্ত হয় — কোড ↔ `.env.example` ↔ `docs/reference/ENVIRONMENT.md` env চুক্তি অক্ষুণ্ণ আছে - [ ] `npm run check:doc-links` 0 কোডসহ সমাপ্ত হয় — পুনর্গঠনের পর কোনো অভ্যন্তরীণ markdown রেফারেন্স ভাঙা নেই - [ ] storage/runtime বিচ্যুতির জন্য `docs/architecture/ARCHITECTURE.md` পর্যালোচনা করা হয়েছে - [ ] env var এবং পরিচালনাগত বিচ্যুতির জন্য `docs/guides/TROUBLESHOOTING.md` পর্যালোচনা করা হয়েছে - [ ] `.env.example` পরিবর্তিত হলে: `docs/reference/ENVIRONMENT.md` হালনাগাদ করা হয়েছে - [ ] নতুন ফিচারের UI থাকলে: `docs/guides/USER_GUIDE.md`-এ সেটির উল্লেখ আছে - [ ] নতুন ফিচারের API থাকলে: `docs/reference/API_REFERENCE.md` + `docs/openapi.yaml` হালনাগাদ করা হয়েছে - [ ] নতুন ফিচারটি একটি module হলে: স্বতন্ত্র `docs/.md` বিদ্যমান - [ ] breaking change হলে: `docs/guides/TROUBLESHOOTING.md`-এ migration নোট আছে ### i18n - [ ] `npm run i18n:check` 0 কোডসহ সমাপ্ত হয় — translation state (`.i18n-state.json`) source docs-এর সঙ্গে সিঙ্ক করা আছে (strict mode-এ কোনো বিচ্যুত source নেই; শেষ মুহূর্তের doc সংশোধনের জন্য warn-mode পরামর্শ গ্রহণযোগ্য, তবে tagging-এর আগে এটি 0 হওয়া উচিত) - [ ] `npm run i18n:check-ui-coverage` 0 কোডসহ সমাপ্ত হয় — প্রতিটি UI locale 80% coverage সীমায় বা তার ওপরে আছে - [ ] `npm run i18n:sync-ui:dry` সব 42টি locale জুড়ে 0টি অনুপস্থিত key রিপোর্ট করে - [ ] source English docs পরিবর্তিত হলে, tagging-এর আগে `npm run i18n:run` চালান (`.env`-এ `OMNIROUTE_TRANSLATION_API_KEY` প্রয়োজন) - [ ] অনুবাদ-সংক্রান্ত অবদান ছোট হলে পরবর্তী release পর্যন্ত স্থগিত রাখা যেতে পারে (CHANGELOG-এ ট্র্যাক করুন) ### Database Migrations - [ ] `src/lib/db/migrations/`-এ নতুন file থাকলে: - [ ] প্রতিটি migration idempotent (`CREATE TABLE IF NOT EXISTS`, ইত্যাদি) - [ ] Migration-গুলো transaction-এ মোড়ানো - [ ] সঠিকভাবে সংখ্যায়িত (ক্রমে কোনো ফাঁক নেই) - [ ] নতুন installation-এ পরীক্ষা করুন: `~/.omniroute/omniroute.db` মুছে `npm run dev` চালান - [ ] বিদ্যমান installation-এ পরীক্ষা করুন: DB backup নিন, migration চালান, schema যাচাই করুন - [ ] migration table পুনর্লিখন করলে WAL file-গুলো (`-wal`, `-shm`) সঠিকভাবে পরিচালিত হয় ### Provider Catalog (Zod দ্বারা যাচাইকৃত) - [ ] `src/shared/constants/providers.ts`-এর Zod schema load-এর সময় বৈধ - [ ] সব provider-এর প্রয়োজনীয় field (`id`, `label`, `kind`, ইত্যাদি) আছে - [ ] নতুন free provider-এর জন্য `freeNote` দেওয়া হয়েছে - [ ] OAuth provider-গুলোর `oauthConfig`, `src/lib/oauth/constants/oauth.ts`-এ নিবন্ধিত আছে - [ ] নতুন provider যোগ করা হলে: `open-sse/executors/`-এ সংশ্লিষ্ট executor আছে - [ ] OpenAI-বহির্ভূত format হলে: `open-sse/translator/`-এ translator আছে - [ ] Model-গুলো `open-sse/config/providerRegistry.ts`-এ নিবন্ধিত - [ ] `tests/unit/`-এর unit test-গুলো provider classification এবং routing অন্তর্ভুক্ত করে ### Desktop (Electron) `electron/` পরিবর্তিত হলে: - [ ] `npm run electron:smoke:packaged` সফল হয় - [ ] `:win`, `:mac`, `:linux`-এর অন্তত একটির জন্য build পরীক্ষা করা হয়েছে - [ ] Code signing cert-এর মেয়াদ শেষ হয়নি (signing করা হলে) - [ ] `electron/package.json`-এর version root `package.json`-এর সঙ্গে মেলে - [ ] `stable`-এ release করা হলে auto-update channel pointer হালনাগাদ করা হয়েছে ### Build Layout Repository-টি তিনটি স্বতন্ত্র output directory ব্যবহার করে — এগুলো কখনো গুলিয়ে ফেলবেন না: | Directory | উদ্দেশ্য | ট্র্যাক করা হয়? | | --------- | ----------------------------------------------------------- | ---------------- | | `src/` | Application source (TypeScript / TSX) | হ্যাঁ | | `.build/` | Build-এর মধ্যবর্তী ফাইল — `next build` output (`distDir`) | না (gitignored) | | `dist/` | বিতরণযোগ্য npm bundle — `assembleStandalone` দ্বারা সংযোজিত | না (gitignored) | > **Operator নোট:** remote VPS image directory এখনও `/usr/lib/node_modules/omniroute/app/`। > শুধু **repository-এর ভেতরের** build output সরানো হয়েছে (`app/` → `dist/`)। Deploy skill-গুলো > `dist/`-এর content remote `app/` directory-তে rsync করে — VPS path পরিবর্তনের প্রয়োজন নেই। **একক-build flow:** ``` npm run build:release └─ rm -rf .build dist (পরিষ্কার) └─ next build → .build/next/ (মধ্যবর্তী ফাইল) └─ assembleStandalone (standalone + static + public + natives → dist/-এ copy করে) └─ writes dist/BUILD_SHA (HEAD sentinel) ``` Deploy-এর জন্য `npm run build` চালিয়ে পরে আলাদাভাবে `npm run build:cli` চালাবেন না — একটিমাত্র command-এ clean rebuild + sentinel সম্পন্ন করতে `npm run build:release` ব্যবহার করুন। ### Artifact Validation - [ ] `npm run build:release` সফল হয় এবং `dist/BUILD_SHA` == `git rev-parse --short HEAD` - [ ] `npm run check:pack-artifact` clean — কোনো `app.__qa_backup`, `scripts/scratch`, `package-lock.json`, বা অন্য local অবশিষ্টাংশ নেই - [ ] build-এর পর `dist/server.js` বিদ্যমান - [ ] ঐচ্ছিক local packaged-runtime smoke: `npm run dev:candidate -- build`-এর পর `npm run dev:candidate -- validate` একটি বিচ্ছিন্ন `DATA_DIR`-এ packed tarball চালু করে এবং `/api/health` + `/v1/models` পরীক্ষা করে ([Contribution Golden Path](CONTRIBUTION_GOLDEN_PATH.md#local-candidate-loop) দেখুন) ### Tagging & Release - [ ] `/generate-release-cc` চালান (Claude Code skill): - `vX.Y.Z` tag তৈরি করে - tag এবং branch push করে - changelog body-সহ GitHub Release খোলে - Electron installer সংযুক্ত করে (build করা থাকলে) - [ ] অথবা manually: ```bash git tag -a vX.Y.Z -m "Release vX.Y.Z" git push origin vX.Y.Z gh release create vX.Y.Z --notes-from-tag ``` ### Deploy Deploy skill-গুলো হালকা rsync flow ব্যবহার করে — `npm pack` বা `npm i -g` নয়: - [ ] লক্ষ্য অনুযায়ী উপযুক্ত deploy skill ব্যবহার করুন: - `/deploy-vps-local-cc` — লোকাল VPS (192.168.0.15) - `/deploy-vps-akamai-cc` — Akamai VPS (69.164.221.35) - `/deploy-vps-both-cc` — উভয়টি - [ ] ডিপ্লয় করার আগে নিশ্চিত করুন যে `dist/BUILD_SHA` == `git rev-parse --short HEAD` - [ ] বিল্ড এমন স্থানে চালাতে হবে যেখানে `node_modules` বাস্তব (মূল checkout অথবা `npm ci` চালানো worktree — symlink করা worktree নয়) - [ ] ডিপ্লয় করা instance-এর smoke test করুন: - `/dashboard/health` খুলুন → version string-টি release-এর সঙ্গে মেলে কি না যাচাই করুন - পরিচিত কোনো provider-এর বিপরীতে একটি `/v1/chat/completions` request চালান - যাচাই করুন যে `/api/monitoring/health` `CLOSED` circuit breaker ফেরত দেয় - নিশ্চিত করুন যে MCP transport-গুলো সাড়া দেয় (`/mcp` HTTP, `/mcp-sse` SSE) ### রিলিজ-পরবর্তী - [ ] `/capture-release-evidences-cc` চালান (Claude Code skill) - নতুন feature-গুলোর WebP screenshot/recording ধারণ করে - release note / blog post-এর সঙ্গে সংযুক্ত করে - [ ] release announcement দিয়ে GitHub Discussions / Discord আপডেট করুন - [ ] পরবর্তী version-এর জন্য milestone খুলুন - [ ] গুরুতর হলে: in-app banner-এর জন্য discussion pin করুন অথবা `news.json`-এ পোস্ট করুন ### Radar public-launch gate Radar announcement-টি ইচ্ছাকৃতভাবে `active: false` সহ commit করা হয়েছে। নিচের প্রতিটি item-এর প্রমাণ পাওয়ার পর activation একটি পৃথক পরিবর্তন হিসেবে করা হবে: - [ ] সব stacked Radar PR merge হয়েছে এবং release-tip CI সবুজ রয়েছে - [ ] `RADAR_ENABLED` ডিফল্টরূপে বন্ধ রেখেই OSS Radar route-গুলো deploy ও smoke test করুন - [ ] নির্ধারিত Radar host-এ `GET /planos`, `/termos`, `/privacidade`, এবং `/reembolso` smoke test করুন - [ ] private service-এ operator-এর পরিচয়/contact/address এবং owner-অনুমোদিত legal review নথিভুক্ত করুন - [ ] শুধু test mode-এ Stripe Checkout এবং signed webhook পরীক্ষা করুন - [ ] অনুমোদিত sender/domain দিয়ে একটি encrypted transactional-email delivery পরীক্ষা করুন - [ ] backup restore এবং তত্ত্বাবধানাধীন, budget-capped একটি research run সফলভাবে প্রমাণ করুন - [ ] donation evidence গ্রহণের আগে BRL/PIX review policy অনুমোদন করুন - [ ] পূর্ববর্তী gate-গুলো অতিক্রম করার পরেই public Checkout চালু করুন, তারপর নতুন `news.json` ID সক্রিয় করুন - [ ] যাচাই করুন যে Home banner localized copy ব্যবহার করে এবং পুরোনো কোনো ID dismiss করার পর নতুন ID পুনরায় প্রদর্শিত হয় ## এমবেডেড সার্ভিস স্মোক পরীক্ষা (v3.8.4+) এমবেডেড সার্ভিসে পরিবর্তন অন্তর্ভুক্ত রয়েছে এমন কোনো রিলিজ প্রকাশের আগে যাচাই করুন: ### নতুন-DB বুট (মাইগ্রেশন সংঘর্ষ শনাক্ত করে — v3.8.4 হটফিক্সের পরে যোগ করা হয়েছে) - [ ] `DATA_DIR=$(mktemp -d) npm start &` — বুটের জন্য 10 সেকেন্ড অপেক্ষা করুন - [ ] `curl -s http://127.0.0.1:20128/api/services/9router/status | jq '.tool'` থেকে `"9router"` ফেরত আসে (404 নয়, 500-ও নয়)। এটি নিশ্চিত করে যে মাইগ্রেশন `071_services.sql` প্রয়োগ করা হয়েছে + সারি সিড করা হয়েছে। - [ ] `sqlite3 $DATA_DIR/storage.sqlite "PRAGMA table_info(version_manager);" | grep -E "provider_expose|logs_buffer_path|last_sync_at"` থেকে 3টি সারি ফেরত আসে। - [ ] `sqlite3 $DATA_DIR/storage.sqlite "PRAGMA table_info(webhooks);" | grep -E "kind|metadata_encrypted"` থেকে 2টি সারি ফেরত আসে (`070_webhooks_kind_metadata.sql` প্রয়োগ করা হয়েছে কিনা তা যাচাই করে)। - [ ] `node --import tsx/esm --test tests/unit/db/no-migration-collisions.test.ts` সফল হয় — ভবিষ্যৎ সংঘর্ষ প্রতিরোধ করে। ### 9Router - [ ] `POST /api/services/9router/install` 2 মিনিটের কম সময়ে `installedVersion`-সহ 200 ফেরত দেয় - [ ] `POST /api/services/9router/start` 30 সেকেন্ডের কম সময়ে 200 এবং `state: "running"` ফেরত দেয় - [ ] `GET /api/services/9router/status` থেকে `health: "healthy"` রিপোর্ট করা হয় - [ ] `"model": "9router/auto/..."`-সহ `POST /v1/chat/completions` থেকে 200 ফেরত আসে (9Router-এর মাধ্যমে এন্ড-টু-এন্ড রাউটিং) - [ ] `GET /dashboard/providers/services/9router/embed/dashboard` প্রক্সির ভেতরে 9Router-এর নেটিভ UI রেন্ডার করে (সরাসরি `127.0.0.1:port` iframe নয়) - [ ] `POST /api/services/9router/rotate-key` থেকে `{ keyRotated: true }` ফেরত আসে এবং সার্ভিসটি পরিষ্কারভাবে পুনরায় চালু হয় - [ ] `POST /api/services/9router/stop` থেকে 200 এবং `state: "stopped"` ফেরত আসে - [ ] `GET /api/services/9router/logs?tail=50` সাম্প্রতিক লাইনসমৃদ্ধ `snapshot` ইভেন্টসহ SSE স্ট্রিম ফেরত দেয় - [ ] PATH-এ `npm` নেই এমন পরিবেশে ইনস্টল করলে ব্যবহারবান্ধব (স্ট্যাক-ট্রেস নয়) ত্রুটি বার্তাসহ 500 ফেরত আসে ### CLIProxyAPI - [ ] `POST /api/services/cliproxy/install` 2 মিনিটের কম সময়ে 200 ফেরত দেয় - [ ] `POST /api/services/cliproxy/start` 30 সেকেন্ডের কম সময়ে 200 এবং `state: "running"` ফেরত দেয় - [ ] `GET /api/services/cliproxy/status` থেকে `health: "healthy"` রিপোর্ট করা হয় - [ ] `POST /api/services/cliproxy/stop` থেকে 200 এবং `state: "stopped"` ফেরত আসে - [ ] `GET /api/services/cliproxy/logs?tail=50` SSE স্ট্রিম ফেরত দেয় ### নিরাপত্তা রিগ্রেশন - [ ] `curl -H "X-Forwarded-For: 1.2.3.4" http://localhost:20128/api/services/9router/start` থেকে `403 LOCAL_ONLY` ফেরত আসে - [ ] `curl -H "X-Forwarded-For: 1.2.3.4" http://localhost:20128/api/services/cliproxy/start` থেকে `403 LOCAL_ONLY` ফেরত আসে - [ ] `/api/services/*` থেকে পাওয়া ত্রুটি প্রতিক্রিয়ায় `err.stack` বা অ্যাবসলিউট ফাইল পাথ থাকে না ## v3.8.0+ যাচাইসমূহ যেকোনো v3.8.x রিলিজ প্রকাশের আগে এই অতিরিক্ত বিষয়গুলো যাচাই করুন: - [ ] `omniroute --tray` macOS-এ বুট হয় (`~/.omniroute/runtime/`-এ systray2 ইনস্টল করা হয়েছে) - [ ] `omniroute --tray` Linux-এ বুট হয় (DISPLAY প্রয়োজন; সেট করা না থাকলে মার্জিতভাবে ত্রুটি দেখায়) - [ ] `omniroute --tray` Windows-এ বুট হয় (PowerShell NotifyIcon, কোনো অতিরিক্ত বাইনারি নয়) - [ ] `omniroute config tray enable` অটোস্টার্ট এন্ট্রি তৈরি করে; disable সেটি সরিয়ে দেয় - [ ] `npm install -g omniroute@` মারাত্মক এক্সিট ছাড়াই postinstall চালায় - [ ] আপডেট পাথ অপশনাল ডিপেন্ডেন্সিগুলো অক্ষুণ্ণ রাখে: `omniroute update --apply` এবং অটো-আপডেটার `npm install -g … --include=optional` চালায়, যাতে `optionalDependencies` (better-sqlite3, keytar, tls-client, এবং llmlingua SLM স্ট্যাক: `@atjsh/llmlingua-2@2.0.5`, `js-tiktoken`) আপডেটের পরেও অক্ষুণ্ণ থাকে। আল্ট্রা `modelPath` SLM টিয়ারের জন্যও tinybert মডেল প্রয়োজন, যা প্রথম ব্যবহারে স্বয়ংক্রিয়ভাবে `${DATA_DIR}/models/llmlingua`-তে ডাউনলোড হয়। এরপর Postinstall (`scripts/build/colocateOptionals.mjs`) SLM-এর অপশনাল ক্লোজারকে `dist/node_modules`-এ সহ-অবস্থান করায়, যাতে ওয়ার্কার একটি একক `@huggingface/transformers` ^4.2.0 ইনস্ট্যান্স রিজলভ করে — স্ট্যান্ডঅ্যালোন ট্রেসে কেবল transformers বান্ডল করা হয়, ডায়নামিকভাবে ইমপোর্ট করা অপশনালগুলো নয়, তাই এটি ছাড়া ওয়ার্কার রুটের transformers-এর বিপরীতে llmlingua-2 লোড করবে এবং SLM টিয়ারটি নীরবে fail-open করবে। - [ ] কোনো `.env` ছাড়াই `omniroute status` কাজ করে (CLI টোকেন পাথ, কেবল লুপব্যাক) - [ ] `curl http://localhost:20128/api/shutdown` থেকে 401 ফেরত আসে (সর্বদা-সুরক্ষিত রুট) - [ ] `curl -H "host: evil.com" http://localhost:20128/api/mcp/sse` থেকে 401 ফেরত আসে (লুপব্যাক গার্ড) - [ ] প্রথমবার চালানোর সময় SQLite রানটাইম `bundled`-এ রিজলভ হয় (বান্ডল করা বাইনারিটি প্ল্যাটফর্মের জন্য বৈধ) - [ ] `node_modules/better-sqlite3` মুছে ফেলা হলে SQLite রানটাইম `runtime`-এ ফলব্যাক করে - [ ] Smart MCP ফিল্টার আসল `playwright-mcp browser_snapshot` আউটপুট সংকুচিত করে (≥50% হ্রাস) - [ ] সব 10টি `skills/omniroute*/SKILL.md` ফাইল raw GitHub URL-এর মাধ্যমে সর্বজনীনভাবে অ্যাক্সেসযোগ্য - [ ] নতুন সেটআপে অনবোর্ডিং উইজার্ড "How It Works" টিয়ার ট্যুর ধাপ দেখায় - [ ] হোম ড্যাশবোর্ডের টিয়ার কভারেজ উইজেট কনফিগার করা/সক্রিয় সংখ্যা দেখায় --- ## 3.9.0 LTS কাট (3.8.58-এ মহড়া করা হয়েছে) v3.8.59-এর পরবর্তী সংস্করণ হলো 3.9.0, এবং এর সর্বশেষ কমিট থেকে দুটি দীর্ঘমেয়াদি ব্রাঞ্চ তৈরি হবে: `stable/v3` (v3 LTS লাইন, npm `latest`) এবং `develop` (v4, 4.0.0-এ উন্নীত, npm `nightly`)। ব্রাঞ্চ/চ্যানেল মডেল, ফরোয়ার্ড-পোর্ট এবং লেবেলসমূহ [RELEASE_STRATEGY.md](./RELEASE_STRATEGY.md)-এ রয়েছে; পরিকল্পনাটি [ROADMAP](../../ROADMAP.md)-এ (Phase 3) রয়েছে। কাটটি একবারই চালানো হবে; 3.8.58 একটি ফর্কে শুরু থেকে শেষ পর্যন্ত এর মহড়া করে, এবং 3.8.59 [GO/NO-GO চেকলিস্ট](./LTS_GO_NO_GO.md) দিয়ে শেষ হয়। ### ড্রাই-রান (শুধু পঠনযোগ্য, যেকোনো সময় নিরাপদ) ```bash npm run release:dry-run-lts-cut # প্রকৃত কাট: HEAD থেকে 3.9.0, পূর্ববর্তী ট্যাগ v3.8.59 npm run release:dry-run-lts-cut -- --from <3.9.0-tip> # সোর্স কমিট নির্দিষ্ট করুন ``` `scripts/release/dry-run-lts-cut.mjs` কিছুই কার্যকর করে না: এটি git ও `gh` থেকে তথ্য পড়ে এবং সম্পূর্ণ ক্রমটি প্রিন্ট করে — পূর্বশর্তসমূহ (সোর্স রিজলভ হয়, সোর্স রিপোজিটরিতে সম্পূর্ণ ইতিহাস রয়েছে — একটি shallow clone থেকে `stable/v3` পুশ করা যায় না, প্রথম grafted parent-এ গ্রহণকারী পক্ষ pack প্রত্যাখ্যান করে, তাই সম্পূর্ণ clone থেকে কাট করুন অথবা প্রথমে `git fetch --unshallow origin` চালান — পূর্ববর্তী ট্যাগ বিদ্যমান, `package.json`-এ লক্ষ্য সংস্করণ রয়েছে, একটি `release-freeze` issue খোলা আছে, বিদ্যমান release branch-এ কোনো খোলা `Release branch not green` issue নেই — যে ব্রাঞ্চ বিদ্যমান নয় সেটি `?` অজানা হিসেবে রিপোর্ট হয়, কখনোই green নয় — Mergify `release` queue কনফিগার করা আছে (G11: `queue_rules`, `checks_timeout`, label `queue`), `release/*` ruleset এখনও মুছে ফেলা ও force-push ব্লক করে, এবং `stable/v3` ও `develop` এখনো বিদ্যমান নয়), দুটি branch ধাপ, কোন dormant-workflow trigger ও `if:` condition সত্য হয় (এবং কোনগুলো repository variable দ্বারা gated থাকে অথবা canonical repository-তে pin করা থাকে), প্রত্যাশিত dist-tagসমূহ (`latest` → 3.9.0, `next` ও `nightly` খালি) এবং rollback। Exit `0` = `RESULT: READY`, `1` = একটি বাধাদানকারী পূর্বশর্ত ব্যর্থ হয়েছে (`✗`), `2` = ব্যবহারজনিত ত্রুটি। `--advisory ` কোনো check-কে না লুকিয়ে warning (`!`)-এ নামিয়ে আনে। 3.9.0 release freeze খোলা থাকা অবস্থাতেই প্রকৃত কাটের dry-run চালান — tag-এর পরে এবং Phase 12c freeze তুলে নেওয়ার আগে branchগুলো তৈরি করা হয়। ### 3.8.58 মহড়া (শুধু fork-এ) ```bash # 1. মহড়ার parameter দিয়ে বর্তমান tip-এ dry-run চালান npm run release:dry-run-lts-cut -- --target-version 3.8.58 --previous-tag v3.8.57 \ --advisory freeze,base-green # 2. একটি FORK remote-এর বিরুদ্ধে চালান (origin, অথবা canonical repository-এর URL-যুক্ত # যেকোনো remote প্রত্যাখ্যান করা হয়; প্রতিটি ধাপে terminal-এ নিশ্চিতকরণ চাওয়া হয়) git remote add rehearsal https://github.com//OmniRoute.git node scripts/release/dry-run-lts-cut.mjs --execute --remote rehearsal \ --target-version 3.8.58 --previous-tag v3.8.57 --advisory freeze,base-green # 3. fork-এ dormant workflowগুলো পরীক্ষা করুন (যেখানে dry-run একটি canonical-repository # pin রিপোর্ট করে সেখানে workflow_dispatch), এরপর rollback করুন node scripts/release/dry-run-lts-cut.mjs --execute --rollback --remote rehearsal \ --target-version 3.8.58 --previous-tag v3.8.57 --advisory freeze,base-green ``` develop bump commitটি git plumbing দিয়ে তৈরি হয় (কোনো working tree স্পর্শ করা হয় না) এবং cycle-open commit-এর মতো একই পাঁচটি file bump করে: `package.json`, `open-sse/package.json`, `electron/package.json`, `package-lock.json` এবং `docs/openapi.yaml`। এরপর `develop`-এ `[4.0.0]` CHANGELOG section ও এর i18n mirrorগুলো খোলা হয়, এর প্রথম PR-এর আগে। scriptটি কখনোই npm dist-tag পরিবর্তন করে না — সেগুলোর মহড়া একটি scratch package-এ করুন। ### PR preview artifact (একবার build করুন, একই byte promote করুন) `.github/workflows/preview-artifact.yml` একটি PR head থেকে একটি production tarball build করে এবং ঠিক সেই build-টিই যাচাই করে (#8084 slice (a))। শুধু একই repository-এর PR; কিছুই publish করা হয় না। ```bash gh workflow run preview-artifact.yml -f pr_number= # অথবা `preview-artifact` label যোগ করুন gh run download --name preview-artifact-pr- --dir preview cd preview && sha256sum -c SHA256SUMS gh attestation verify omniroute-*.tgz --repo diegosouzapw/OmniRoute npm install -g ./omniroute-*.tgz # preview install ``` runটি `npm ci`, `npm run build:release`, `npm run check:pack-artifact` চালায়, tarballটি pack করে, `npm run check:pack-boot` (নকল secret, ক্ষণস্থায়ী data dir) চালায়, পুনরায় pack করে এবং digest অভিন্ন না হলে ব্যর্থ হয়; এরপর `artifact-identity.json`-এ (head SHA, base SHA, lockfile hash, platform, arch, node ABI, bundler, build policy — `scripts/release/artifact-identity.mjs`) তথ্য রেকর্ড করে এবং একটি পৃথক job-এ tarballটির attestation তৈরি করে। কোনো preview promote করার অর্থ হলো সেই tarballটি install করা: source থেকে কখনোই পুনরায় build করবেন না। ### কাট (3.9.0, GO-এর পরে) 1. [LTS_GO_NO_GO.md](./LTS_GO_NO_GO.md)-এ GO রেকর্ড করা হয়েছে। 2. `npm run release:dry-run-lts-cut -- --from v3.9.0` চালালে `RESULT: READY` প্রিন্ট হয়। 3. dry-run যে commandগুলো প্রিন্ট করে, সেগুলো দিয়ে হাতে `origin`-এ branchগুলো তৈরি করুন — scriptটি `origin`-এ push করতে অস্বীকার করে। review করা develop commit পুনরায় ব্যবহার করতে, প্রথমে 3.9.0 tip থেকে আপনার fork-এর বিরুদ্ধে `--execute` মহড়া চালান; এটি উভয় SHA প্রিন্ট করে, এবং একই commitগুলো push করা যাবে: ```bash git push origin :refs/heads/stable/v3 :refs/heads/develop ``` 4. প্রথম PR মার্জ হওয়ার আগে `stable/v3` এবং `develop` সুরক্ষিত করুন (রুলসেট + মার্জ কিউ)। 5. ব্রাঞ্চের অস্তিত্বের ভিত্তিতে নিষ্ক্রিয় ওয়ার্কফ্লোগুলো সক্রিয় হয়: `forward-port.yml` (`stable/v3`-এ push), `validate-stable-pr.yml` (`stable/v3`-এর জন্য PR) এবং `nightly-v4-build.yml` (`develop` বিল্ড করে)। চালু করার আগে `secrets.FORWARD_PORT_TOKEN` রিপোজিটরি সিক্রেট সেট করুন (যাতে forward-port PR-গুলোতে CI চলে); মালিক রিপোজিটরি ভেরিয়েবল `vars.NIGHTLY_PUBLISH`-কে `true` হিসেবে সেট না করা এবং npm Trusted Publishing কর্তৃক `nightly-v4-build.yml` গৃহীত না হওয়া পর্যন্ত nightly প্রকাশনা বন্ধ থাকবে। চ্যানেল নির্ধারণের কাজটি করে `scripts/release/dist-tag.mjs`, একই রিজলভার যা `npm-publish.yml` ব্যবহার করে। 6. চ্যানেলগুলো যাচাই করুন: `npm view omniroute dist-tags --json`-এর আউটপুটে `latest` = 3.9.0 দেখায় এবং v4 প্রকাশিত না হওয়া পর্যন্ত কোনো `next` / `nightly` থাকে না। 7. প্রয়োজন হলে রোলব্যাক করুন: `git push origin --delete refs/heads/stable/v3 refs/heads/develop` এবং `npm dist-tag add omniroute@3.8.59 latest`। --- ## রোলব্যাক রিলিজে গুরুতর সমস্যা থাকলে: 1. `gh release edit vX.Y.Z --prerelease` (সর্বশেষ নয় হিসেবে চিহ্নিত করে) 2. `git tag -d vX.Y.Z && git push --delete origin vX.Y.Z` (শুধু যদি ব্যবহারকারীরা এখনও এটি গ্রহণ না করে থাকেন) 3. অথবা: `release/vX.Y.0`-এ হটফিক্স → প্যাচ রিলিজ `vX.Y.(Z+1)` 4. অবিলম্বে GitHub Discussions এবং Discord-এ জানান ## কঠোর নিয়মাবলি - কখনোই সরাসরি `main`-এ কমিট করবেন না - `main` বা `release/*` ব্রাঞ্চে কখনোই `git push --force` ব্যবহার করবেন না - কখনোই Husky হুক এড়িয়ে যাবেন না (`--no-verify`) - কখনোই সিক্রেট, ক্রেডেনশিয়াল বা `.env` ফাইল কমিট করবেন না - কভারেজ অবশ্যই ≥60/60/60/60 (স্টেটমেন্ট/লাইন/ফাংশন/ব্রাঞ্চ) বজায় রাখতে হবে - `src/`, `open-sse/`, `electron/` বা `bin/`-এর প্রোডাকশন কোড পরিবর্তন করার সময় সর্বদা টেস্ট যোগ বা আপডেট করুন ## স্বয়ংক্রিয় সিঙ্ক যাচাই PR খোলার আগে স্থানীয়ভাবে ডকুমেন্টেশন সিঙ্ক গার্ড চালান: ```bash npm run check:docs-sync ``` CI-ও `.github/workflows/ci.yml`-এ (লিন্ট জব) এই যাচাই চালায়।