diff --git a/docs/initiatives/0011-foundation-adoption-and-process-discipline.md b/docs/initiatives/0011-foundation-adoption-and-process-discipline.md index e7460c942..f42bfb8c8 100644 --- a/docs/initiatives/0011-foundation-adoption-and-process-discipline.md +++ b/docs/initiatives/0011-foundation-adoption-and-process-discipline.md @@ -1,7 +1,7 @@ # 0011 — Foundation adoption + process discipline (post-launch sweep) > **Last validated:** 2026-05-04 by @Skords-01. **Next review:** 2026-08-02. -> **Status:** Phase 1 ~70% done (1.1/1.2/1.3 merged; 1.4 pending). Phase 2 in flight: 2.2 merged (#1696); 2.4 (#1703) + 2.5 (#1709) + 2.6 (#1713) + 2.7 (#1714) + 2.8 (#1726) opened 2026-05-04 (DataState consumer adoption — finyk + fizruk + nutrition + routine + digest closes the consumer-adoption block; 2.9 ESLint rule і 2.1 ManualExpenseSheet залишаються). +> **Status:** **Phase 1 complete** — 4/4 PR-ів merged станом на 2026-05-04. Phase 2 in flight: 2.2 merged (#1696); 2.4 (#1703) + 2.5 (#1709) + 2.6 (#1713) + 2.7 (#1714) + 2.8 (#1726) opened 2026-05-04 (DataState consumer adoption — finyk + fizruk + nutrition + routine + digest closes the consumer-adoption block; 2.9 ESLint rule і 2.1 ManualExpenseSheet залишаються). Phases 3–4 заплановані пост-0010-launch ≥ 2026-06-01. > **Priority:** P1 (subordinate to 0010-revenue-first-launch scope-freeze) > **Owner:** `@Skords-01` > **ETA:** 7 тижнів (Phase 1 — паралельно з 0010 freeze; Phases 2–4 — після 0010 launch) @@ -45,48 +45,47 @@ ### Фаза 1 — Process discipline (CI guards) — 1 тиждень, 2026-05-05 → 2026-05-12 _(паралельно з 0010 freeze — in-scope)_ -**PR 1.1 — `ci(governance): fail PR with empty body or unfilled template`** (P0) - -- Файл: `.github/workflows/pr-quality.yml` (новий) + `scripts/.mjs` (новий — placeholder). -- Аналог existing `scripts/check-skill-shape.mjs` за стилем. -- Логіка: GitHub Actions trigger `pull_request: [opened, edited, synchronize]`. Зчитує `${{ github.event.pull_request.body }}`. Падає якщо: - - Тіло порожнє (length < 50 chars після обрізання whitespace/HTML-comment-ів). - - Не містить хоча б одного з заповнених sections з `.github/PULL_REQUEST_TEMPLATE.md` (заголовки `## Summary`, `## Verification` мають мати непорожній текст під собою). - - `Hard Rule #15` чек-боксів не tick-нуто (3 з 3 мають бути `[x]`). -- Винятки: PR-и з лейблом `meta` або від `dependabot[bot]` / `renovate[bot]` (Renovate / Dependabot заповнюють body автогенеровано). -- Тести: `scripts/.test.mjs` з 6+ кейсами (порожнє, тільки template, заповнене, dependabot-PR, renovate-PR, Hard Rule #15 не позначений). -- **Закриває:** PR #1571 type-incident. -- **Risk:** низький. Зміна — тільки GitHub Actions, не runtime. - -**PR 1.2 — `ci(migrations): cross-branch collision pre-merge guard`** (P0) - -- Файл: розширення `scripts/lint-migrations.mjs` + новий job у `.github/workflows/ci.yml`. -- Логіка: на `pull_request` (event type `synchronize` після rebase) перевіряємо: чи у поточному PR є новий міграційний файл `NNN_*.sql`. Якщо так — fetch-имо `origin/main` і перевіряємо, що `NNN` строго більше за `max(numbers in main:apps/server/src/migrations)`. Якщо ні — fail з порадою «rebase + renumber». -- Поточний `lint-migrations.mjs` ловить тільки **внутрішньо-PR** дублікати; цей extend ловить cross-branch. -- Тести: інтеграційний у `scripts/__tests__/.test.mjs` (з мокнутим `git ls-files`). -- **Закриває:** PR #1652 type-incident. -- **Risk:** низький. Рестроспективно перевіримо, що `git fetch` доступний у CI runner-і (вже є — `actions/checkout@v4` із `fetch-depth: 0` у `ci.yml`). - -**PR 1.3 — `ci(deploy): require staging-verification label for vercel.json / fly.toml / railway.toml changes`** (P1) - -- Файл: розширення `.github/workflows/pr-quality.yml` (з PR 1.1) + новий step. -- Логіка: якщо diff PR торкається `**/vercel.json` або `**/fly.toml` або `**/railway.toml` або `**/Dockerfile*` або `apps/server/build.mjs` — fail без лейбла `verified-on-staging` (повинен бути доданий вручну після того, як автор підтвердив deploy на staging-environment). -- Винятки: only-comment-додаток (детектиш через `diff --stat`), pure rename без зміни ключів. -- Документ: `docs/playbooks/deploy-config-change.md` — як саме верифікувати staging. -- **Закриває:** PR #1595 → #1600 type-incident. -- **Risk:** середній. Може уповільнити hot-fix-и — митиґуємо через `verified-on-staging-emergency` лейбл з обов'язковим post-mortem. - -**PR 1.4 — `docs(incidents): CSP_DISABLE kill-switch retrospective audit`** (P1) - -- Файл: `docs/incidents/2026-05-04-csp-disable-audit.md` (новий) + посилання з `docs/runbooks/`. -- Скоуп: перевірити Railway env-var history (production + staging), git-blame для `CSP_DISABLE` додавання (`git log --all -S "CSP_DISABLE"`), Sentry-логи на CSP-violation-dropouts. Записати: - - Коли і ким додано прапорець (commit + дата). - - Чи був enabled у prod (Railway env-var snapshots). - - Якщо так — на скільки часу і чи були CSP-violation-події в той період. - - Lessons learned + чи треба disclosure. -- Якщо `CSP_DISABLE` ніколи не був true в prod → закриваємо як «zero-impact retrospective». -- Якщо був true → еacalation-path до 0008 phase 1 + потенційний `docs/security/disclosures/` запис. -- **Risk:** низький (read-only audit). Залежність — Railway env-history retention (зазвичай 90 днів — може бути часткове покриття). +**Status: 4/4 PR-ів merged станом на 2026-05-04.** Phase 1 завершено повністю; залишаються лише 5 operational action items з PR 1.4 на @Skords-01 з due-date 2026-05-11. + +**PR 1.1 — `ci(root): require all Hard Rule #15 boxes ticked in PR body`** (P0) — **MERGED [#1688](https://github.com/Skords-01/Sergeant/pull/1688)** + +- **Pivot під час реалізації:** оригінальний план казав «новий `pr-quality.yml` + новий `.mjs`», але `scripts/ci/validate-pr-body.mjs` **уже існував** і вже перевіряв 7 секцій + non-empty body + ≥1 ticked checkbox. Створювати другий validator = той самий дубляж, який цей initiative закриває (Renovate × Dependabot ~4 тижні). +- **Реальна зміна:** додано `SECTIONS_REQUIRING_ALL_TICKED = ["Hard Rule #15"]`. Hard Rule #15 тепер валідується суворо **3-of-3 ticked**, бо кожен box — binary, factually-verifiable (read AGENTS.md / Ukrainian / no `--no-verify`). `Docs and Governance` лишається `≥1` (там є explicit `N/A` box). +- **+60 / −7 LOC у двох файлах. Тести:** 8 → 11 pass (нові: 1/3, 2/3, 3/3 grid). +- **Self-test:** validator валідує тіло цього ж PR-у, тож CI green = він працює. +- **Закрив:** PR #1571 type-incident (PR з порожнім тілом merged into main). + +**PR 1.2 — `ci(server): cross-branch migration-number collision guard`** (P0) — **MERGED [#1691](https://github.com/Skords-01/Sergeant/pull/1691)** + +- Розширення `scripts/lint-migrations.mjs` (без нового workflow YAML — re-use existing `migration-lint` job, який вже має `fetch-depth: 0`). +- Три нові helper-и (`listMigrationsOnRef`, `filterNewMigrationFiles`, `findCrossBranchCollisions`) + step 2a у `run()`. Перевіряє тільки `git diff --diff-filter=A` (newly-added) → modified files (M) НЕ flag-ляться як колізії. +- Graceful fallback: якщо `origin/main` недоступний — крок скіпається, lint degrades до prior behaviour. +- **Тести:** 28 → 41 pass (+13 нових). Black-box-сімуляція колізії: error-message правильно іменує файл і дає `rebase + renumber` guidance. +- **Закрив:** PR #1652 type-incident (та ж колізія, що сталась з 0010/0011 номерами під час підготовки цього initiative-document-у — meta!). + +**PR 1.3 — `ci(root): require staging-verification label for deploy-config changes`** (P1) — **MERGED [#1697](https://github.com/Skords-01/Sergeant/pull/1697)** + +- Новий workflow `.github/workflows/deploy-config-staging-gate.yml` + supporting script `scripts/ci/check-deploy-config-staging-gate.mjs`. +- Тригер: `pull_request: [opened, synchronize, reopened, labeled, unlabeled]`. Гейтить deploy-config файли: `vercel.json` (anywhere), `fly.toml`, `railway.toml`, `Dockerfile*` (basename), `Caddyfile`, `apps/server/build.mjs`. +- Comment-aware exemption per dialect: `none` (JSON, no comments), `hash` (TOML / Dockerfile / Caddyfile), `js` (build.mjs). Pure-comment / pure-whitespace diffs auto-skip the gate. +- Required labels: `verified-on-staging` (normal flow per playbook) OR `verified-on-staging-emergency` (escape-hatch with post-mortem commitment). +- **Тести:** 31 unit-test покриття (dispatch matchers, comment-only detection across 3 dialects, label parsing edge cases, full `evaluate()` integration). +- **Новий playbook:** `docs/playbooks/deploy-config-change.md` — decision tree (Mermaid) + per-surface verification steps (Vercel preview / Fly staging / Railway service) + emergency escape-hatch protocol. Зареєстровано у `playbook-catalog.md` + auto-regenerated INDEX.md. +- **Закрив:** PR #1595 → #1600 type-incident (Vercel SSOT-flip). + +**PR 1.4 — `docs(docs): csp-disable retrospective audit`** (P1) — **MERGED [#1699](https://github.com/Skords-01/Sergeant/pull/1699)** + +- Файл: `docs/audits/2026-05-04-csp-disable-retrospective.md` (а не `docs/incidents/...` як було у початковому плані — у репо вже існує `docs/audits/` як convention для retrospective-документів; `docs/postmortems/` зарезервовано для real incidents з confirmed user-impact). +- Зареєстровано у `docs/audits/README.md` як Active / 0-of-5 implemented. +- **Git-log investigation проведена:** `CSP_DISABLE` введено 2026-04-18 у [PR #128](https://github.com/Skords-01/Sergeant/pull/128) (commit `01914d34` — DevinAI feat strict API CSP), warn-on-boot-log додано через 24 години у [PR #345](https://github.com/Skords-01/Sergeant/pull/345) (commit `97ed26e9`), deep security review M1 зафіксував CVSS 6.1 на 2026-05-03, видалення з коду + EnvSchema 2026-05-04 у [PR #1631](https://github.com/Skords-01/Sergeant/pull/1631) (commit `de602495`). Total lifetime: 16 днів. +- **Open questions Q1–Q4 → action items A1–A5 на @Skords-01** з due-date 2026-05-11: + - A1 — підтвердити Railway env-cleanup (production + staging) і записати pre-existing-value + - A2 — експортувати Railway audit-log за 2026-04-18 → 2026-05-04 (або зафіксувати tier-limitation) + - A3 — Sentry-query: `event.type:default AND (message:csp_disabled OR message:"csp-report")` + - A4 — додати retroactive-row у `secret-ownership-register.md` + - A5 — verify, що PR 1.3 staging-gate **НЕ** покриває runtime env-var changes у Railway dashboard (це окремий клас ризику; потрібна окрема ініціатива) +- Severity: **SEV4 near-miss** (no confirmed user-impact, але structural risk був реальним). +- **Закриває:** zombie-incident PR #1631 (operational boundary, явно deferred у Resolution log самої М1-картки). ### Фаза 2 — Foundation adoption (consumer migrations) — 3 тижні, 2026-06-02 → 2026-06-23 _(поста-0010-launch)_ diff --git a/docs/initiatives/README.md b/docs/initiatives/README.md index eb960656e..90529183b 100644 --- a/docs/initiatives/README.md +++ b/docs/initiatives/README.md @@ -28,19 +28,19 @@ ## Активні ініціативи (травень 2026) -| # | Назва | Пріоритет | Власник | ETA | Статус | -| ---- | -------------------------------------------------------------------------------------------------------------------- | --------- | ------------ | ------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| 0001 | [Module decomposition + `max-lines` guard](./0001-module-decomposition.md) | P0 | `@Skords-01` | Sprint 1 (2 wk) | **Done** (2026-05-04) — Phase 1 [#1555](https://github.com/Skords-01/Sergeant/pull/1555) + Phase 2 [#1593](https://github.com/Skords-01/Sergeant/pull/1593) [#1594](https://github.com/Skords-01/Sergeant/pull/1594) [#1596](https://github.com/Skords-01/Sergeant/pull/1596) [#1597](https://github.com/Skords-01/Sergeant/pull/1597) [#1603](https://github.com/Skords-01/Sergeant/pull/1603) + Phase 3 finalize. 5 з 5 запланованих топ-1 моноліт-файлів декомпоновано. Lint guard active. Carry-over (FinykApp, Workouts, drift) → successor. | -| 0002 | [Mobile platform decision](./0002-mobile-platform-decision.md) | P0 | `@Skords-01` | Sprint 1 (2 wk) | In progress (Phase 1 — sunset locked, lint guard live, PR open) + Phase 2 [#1633](https://github.com/Skords-01/Sergeant/pull/1633) (weekly `shell-tax-report.yml` cron — авто-issue з reminder про deprecation, T-30/T-7/T-1 cadence). | -| 0003 | [Sync v2 rollout & v1 sunset](./0003-sync-v2-rollout-and-v1-sunset.md) | P0 | `@Skords-01` | Sprint 1–2 | In progress (2026-05-04) — Phase 1 [#1621](https://github.com/Skords-01/Sergeant/pull/1621) (`sync_v1_legacy_clients_total` survey counter + 3 Grafana panels + 3 recording rules) + Phase 2 (RFC 8594 `Sunset:`/`Deprecation:` + RFC 8288 `Link:` middleware на v1 routes + [ADR-0043](../adr/0043-cloudsync-v1-sunset.md)). Phase 3-6 (feature-flag + backfill + T₀ → 410 Gone + cleanup) — pending, gated на baseline-week measurement. | -| 0004 | [Server observability (Sentry + OTel)](./0004-server-observability.md) | P0 | `@Skords-01` | Sprint 1 (1 wk) | **Done** (2026-05-04) — Sentry server-side + ALS context + `traceparent` middleware + 9 Grafana dashboards + Prom alerts шипнуто. OTEL distributed tracing → carry-over до [ADR-0035](../adr/0035-distributed-tracing-opentelemetry.md) follow-up. | -| 0005 | [AI cost optimisation (prompt cache)](./0005-ai-cost-and-prompt-cache.md) | P0 | `@Skords-01` | Sprint 1 (3 dni) | **Done** (2026-05-04) — Prompt-cache на 2 breakpoints (`system[0]` + last tool) у `chat.ts`, `ai_tokens_total` / `ai_cost_estimate_usd_total` / `anthropic_prompt_cache_hit_total` Prom counters, 7-panel `ai-cost.json` Grafana, alerts. Policy зафіксована в [ADR-0039](../adr/0039-anthropic-prompt-cache-policy.md). | -| 0006 | [Frontend routing & code-split](./0006-frontend-routing-and-code-split.md) | P1 | `@Skords-01` | Sprint 2 (2 wk) | **In progress** — Phase 0 [#1657](https://github.com/Skords-01/Sergeant/pull/1657) (lint canary `sergeant-design/no-hash-router-in-modules` warn-only + baseline 18 warnings / 10 файлів). Phase 1 (`react-router@7` setup) — наступний крок. | -| 0007 | [Design-system tooling (Storybook + VR)](./0007-design-system-tooling.md) | P1 | `@Skords-01` | Sprint 2 (2 wk) | Proposed | -| 0008 | [Platform hardening (rate-limit, health)](./0008-platform-hardening.md) | P1 | `@Skords-01` | Sprint 2 (1 wk) | **In progress** (2026-05-04) — Phase 1 [#1634](https://github.com/Skords-01/Sergeant/pull/1634) (`/startupz` + nested `/health/{liveness,readiness,startup}` aliases + 6 smoke tests) + Phase 2 [#1638](https://github.com/Skords-01/Sergeant/pull/1638) (centralized `RATE_LIMIT_POLICIES` registry + RFC-9239 `RateLimit-*` headers + auth migration + 12 tests) + Phase 3 [#1641](https://github.com/Skords-01/Sergeant/pull/1641) (Renovate primary + Dependabot security-only daily, [ADR-0044](../adr/0044-renovate-vs-dependabot.md), `anthropic`/`sentry`/`opentelemetry` groups) + Phase 4 [#1639](https://github.com/Skords-01/Sergeant/pull/1639) (`release-sbom.yml` workflow → SPDX + CycloneDX на published release / git tag / manual dispatch, anchore/sbom-action SHA-pinned) + Phase 5 [#1642](https://github.com/Skords-01/Sergeant/pull/1642) (runbook FAQ для probes / 429 / Renovate / SBOM). Pending merge ладают до **Done**. | -| 0009 | [Agent-OS hardening (skills/playbooks/governance gates)](./0009-agent-os-hardening.md) | P1 | `@Skords-01` | Sprint 2–3 (4 wk) | **In progress** (2026-05-04) — Phase 1: 2/5 PR merged ([#1659](https://github.com/Skords-01/Sergeant/pull/1659) `pnpm lint:skills` + skills-lock SHA-256 enforcement, [#1660](https://github.com/Skords-01/Sergeant/pull/1660) Hard Rules registry `category` taxonomy 6/11/1). PR 1.3 (`tsc-files` pre-commit) deferred — заблоковано pre-existing typecheck помилками на `main` (`apps/server/.../rotateSecret.test.ts` TS2345 + `apps/web/.../HubDashboard.tsx` TS2741); потрібен hotfix-PR перед активацією. Залишок Phase 1: PR 1.2 (UA-prose linter), PR 1.4 (`playbook-schema` extension). | -| 0010 | [Revenue-first launch (Stripe MVP + Apple/Google auth + Mono-wedge)](./0010-revenue-first-launch.md) | P0 | `@Skords-01` | Sprint 1–4 (4 wk) | Proposed (2026-05-04, decisions locked) — фаза 0 (цей PR з аудит-сорсом + initiative-документом + owner-decisions). Фази 1–6: ADR pricing v3 ($7/міс, ₴UA-only, trial без картки) + ADR mobile-strategy (Capacitor primary, Expo paralleled) → `subscriptions` міграції + Stripe SDK + webhook → paywall UI + real `/pricing` CTA + Apple/Google/Email auth → activation v2 (Mono-wedge) + A/B onboarding → public landing + EN-локаль. **OpenClaw НЕ freeze** (active parallel). **Public metrics — deferred.** Source: [`docs/audits/2026-05-04-revenue-and-marketing-roast.md`](../audits/2026-05-04-revenue-and-marketing-roast.md). | -| 0011 | [Foundation adoption + process discipline (post-launch sweep)](./0011-foundation-adoption-and-process-discipline.md) | P1 | `@Skords-01` | Sprint 2 (Phase 1) + post-0010 (Phases 2–4, 6 wk) | **Proposed** (2026-05-04) — subordinate to [0010-revenue-first-launch](./0010-revenue-first-launch.md) freeze. 18 PR-ів у 4 фазах: Phase 1 (4 PR, in-freeze CI-guards: PR-template / cross-branch migration-collision / vercel-staging gate / CSP_DISABLE retrospective) — старт 2026-05-05, паралельно з 0010. Phases 2–4 (foundation adoption + hardening verification + Storybook hand-off) — після 0010 launch, ~2026-06-02 → 2026-07-14. Real baseline: 2 active `useFormValidation`, 6 `useApiForm`, 0 real `` consumers, 15 manual `isLoading/isError`, 0 raw `fetch()`. Source: vector assessment 2026-05-04. | +| # | Назва | Пріоритет | Власник | ETA | Статус | +| ---- | -------------------------------------------------------------------------------------------------------------------- | --------- | ------------ | ------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| 0001 | [Module decomposition + `max-lines` guard](./0001-module-decomposition.md) | P0 | `@Skords-01` | Sprint 1 (2 wk) | **Done** (2026-05-04) — Phase 1 [#1555](https://github.com/Skords-01/Sergeant/pull/1555) + Phase 2 [#1593](https://github.com/Skords-01/Sergeant/pull/1593) [#1594](https://github.com/Skords-01/Sergeant/pull/1594) [#1596](https://github.com/Skords-01/Sergeant/pull/1596) [#1597](https://github.com/Skords-01/Sergeant/pull/1597) [#1603](https://github.com/Skords-01/Sergeant/pull/1603) + Phase 3 finalize. 5 з 5 запланованих топ-1 моноліт-файлів декомпоновано. Lint guard active. Carry-over (FinykApp, Workouts, drift) → successor. | +| 0002 | [Mobile platform decision](./0002-mobile-platform-decision.md) | P0 | `@Skords-01` | Sprint 1 (2 wk) | In progress (Phase 1 — sunset locked, lint guard live, PR open) + Phase 2 [#1633](https://github.com/Skords-01/Sergeant/pull/1633) (weekly `shell-tax-report.yml` cron — авто-issue з reminder про deprecation, T-30/T-7/T-1 cadence). | +| 0003 | [Sync v2 rollout & v1 sunset](./0003-sync-v2-rollout-and-v1-sunset.md) | P0 | `@Skords-01` | Sprint 1–2 | In progress (2026-05-04) — Phase 1 [#1621](https://github.com/Skords-01/Sergeant/pull/1621) (`sync_v1_legacy_clients_total` survey counter + 3 Grafana panels + 3 recording rules) + Phase 2 (RFC 8594 `Sunset:`/`Deprecation:` + RFC 8288 `Link:` middleware на v1 routes + [ADR-0043](../adr/0043-cloudsync-v1-sunset.md)). Phase 3-6 (feature-flag + backfill + T₀ → 410 Gone + cleanup) — pending, gated на baseline-week measurement. | +| 0004 | [Server observability (Sentry + OTel)](./0004-server-observability.md) | P0 | `@Skords-01` | Sprint 1 (1 wk) | **Done** (2026-05-04) — Sentry server-side + ALS context + `traceparent` middleware + 9 Grafana dashboards + Prom alerts шипнуто. OTEL distributed tracing → carry-over до [ADR-0035](../adr/0035-distributed-tracing-opentelemetry.md) follow-up. | +| 0005 | [AI cost optimisation (prompt cache)](./0005-ai-cost-and-prompt-cache.md) | P0 | `@Skords-01` | Sprint 1 (3 dni) | **Done** (2026-05-04) — Prompt-cache на 2 breakpoints (`system[0]` + last tool) у `chat.ts`, `ai_tokens_total` / `ai_cost_estimate_usd_total` / `anthropic_prompt_cache_hit_total` Prom counters, 7-panel `ai-cost.json` Grafana, alerts. Policy зафіксована в [ADR-0039](../adr/0039-anthropic-prompt-cache-policy.md). | +| 0006 | [Frontend routing & code-split](./0006-frontend-routing-and-code-split.md) | P1 | `@Skords-01` | Sprint 2 (2 wk) | **In progress** — Phase 0 [#1657](https://github.com/Skords-01/Sergeant/pull/1657) (lint canary `sergeant-design/no-hash-router-in-modules` warn-only + baseline 18 warnings / 10 файлів). Phase 1 (`react-router@7` setup) — наступний крок. | +| 0007 | [Design-system tooling (Storybook + VR)](./0007-design-system-tooling.md) | P1 | `@Skords-01` | Sprint 2 (2 wk) | Proposed | +| 0008 | [Platform hardening (rate-limit, health)](./0008-platform-hardening.md) | P1 | `@Skords-01` | Sprint 2 (1 wk) | **In progress** (2026-05-04) — Phase 1 [#1634](https://github.com/Skords-01/Sergeant/pull/1634) (`/startupz` + nested `/health/{liveness,readiness,startup}` aliases + 6 smoke tests) + Phase 2 [#1638](https://github.com/Skords-01/Sergeant/pull/1638) (centralized `RATE_LIMIT_POLICIES` registry + RFC-9239 `RateLimit-*` headers + auth migration + 12 tests) + Phase 3 [#1641](https://github.com/Skords-01/Sergeant/pull/1641) (Renovate primary + Dependabot security-only daily, [ADR-0044](../adr/0044-renovate-vs-dependabot.md), `anthropic`/`sentry`/`opentelemetry` groups) + Phase 4 [#1639](https://github.com/Skords-01/Sergeant/pull/1639) (`release-sbom.yml` workflow → SPDX + CycloneDX на published release / git tag / manual dispatch, anchore/sbom-action SHA-pinned) + Phase 5 [#1642](https://github.com/Skords-01/Sergeant/pull/1642) (runbook FAQ для probes / 429 / Renovate / SBOM). Pending merge ладают до **Done**. | +| 0009 | [Agent-OS hardening (skills/playbooks/governance gates)](./0009-agent-os-hardening.md) | P1 | `@Skords-01` | Sprint 2–3 (4 wk) | **In progress** (2026-05-04) — Phase 1: 2/5 PR merged ([#1659](https://github.com/Skords-01/Sergeant/pull/1659) `pnpm lint:skills` + skills-lock SHA-256 enforcement, [#1660](https://github.com/Skords-01/Sergeant/pull/1660) Hard Rules registry `category` taxonomy 6/11/1). PR 1.3 (`tsc-files` pre-commit) deferred — заблоковано pre-existing typecheck помилками на `main` (`apps/server/.../rotateSecret.test.ts` TS2345 + `apps/web/.../HubDashboard.tsx` TS2741); потрібен hotfix-PR перед активацією. Залишок Phase 1: PR 1.2 (UA-prose linter), PR 1.4 (`playbook-schema` extension). | +| 0010 | [Revenue-first launch (Stripe MVP + Apple/Google auth + Mono-wedge)](./0010-revenue-first-launch.md) | P0 | `@Skords-01` | Sprint 1–4 (4 wk) | Proposed (2026-05-04, decisions locked) — фаза 0 (цей PR з аудит-сорсом + initiative-документом + owner-decisions). Фази 1–6: ADR pricing v3 ($7/міс, ₴UA-only, trial без картки) + ADR mobile-strategy (Capacitor primary, Expo paralleled) → `subscriptions` міграції + Stripe SDK + webhook → paywall UI + real `/pricing` CTA + Apple/Google/Email auth → activation v2 (Mono-wedge) + A/B onboarding → public landing + EN-локаль. **OpenClaw НЕ freeze** (active parallel). **Public metrics — deferred.** Source: [`docs/audits/2026-05-04-revenue-and-marketing-roast.md`](../audits/2026-05-04-revenue-and-marketing-roast.md). | +| 0011 | [Foundation adoption + process discipline (post-launch sweep)](./0011-foundation-adoption-and-process-discipline.md) | P1 | `@Skords-01` | Sprint 2 (Phase 1) + post-0010 (Phases 2–4, 6 wk) | **In progress** (2026-05-04) — subordinate to [0010-revenue-first-launch](./0010-revenue-first-launch.md) freeze. **Phase 1: 4/4 PR-ів** — 4 merged: [#1688](https://github.com/Skords-01/Sergeant/pull/1688) `validate-pr-body.mjs` Hard Rule #15 strict 3-of-3 ticked (closes PR #1571 type-incident), [#1691](https://github.com/Skords-01/Sergeant/pull/1691) cross-branch migration-collision guard у `lint-migrations.mjs` (+13 tests, closes PR #1652 type-incident), [#1697](https://github.com/Skords-01/Sergeant/pull/1697) deploy-config staging-verification label gate (`deploy-config-staging-gate.yml` + 31 tests, closes PR #1595→#1600 Vercel SSOT-flip), [#1699](https://github.com/Skords-01/Sergeant/pull/1699) CSP_DISABLE retrospective audit (`docs/audits/2026-05-04-csp-disable-retrospective.md`, 5 action items на @Skords-01 due 2026-05-11, closes zombie-incident PR #1631). Phases 2–4 (foundation adoption + hardening verification + Storybook hand-off) — після 0010 launch, ~2026-06-02 → 2026-07-14. Real baseline: 2 active `useFormValidation`, 6 `useApiForm`, 0 real `` consumers, 15 manual `isLoading/isError`, 0 raw `fetch()`. Source: vector assessment 2026-05-04. | ## Статуси