End-to-end walkthrough: Login Flow для AcmeCorp
Один полный цикл RENAR от подписанного ТЗ до accepted release. Пример — внутренний инструмент с регистрацией через корпоративный email и 2FA. Цель — показать все этапы на одном среднем по размеру проекте.
Контекст: AcmeCorp, ~1 спринт работы команды, стек Next.js + FastAPI + PostgreSQL. RENAR-зрелость уровня RENAR-3+ (полный ADAPT + TC + adversarial). Substrate в примерах — git + tausik runtime; substrate-agnostic core применим на любом substrate с capabilities V1-V6.
Предпосылки: 00-quickstart, core/renar-core, reference/01-glossary.
Phase 0 — Elicitation
До подписания ТЗ. AI-агент проводит 2-3 интервью с stakeholder’ами (Sales Director, IT Manager) и собирает контекст в structured form.
Артефакты Phase 0 (informative, не нормативные для RENAR Core):
acmecorp-login.req/
elicitation/
domain-context.md # домен и его особенности
sales-director.yaml # transcripts + structured findings
it-manager.yaml
findings-clustered.md # сгруппированные находки
critic-review.md # adversarial review draft требований
multi-model-diff.md # разногласия двух моделей
Phase 0 не нормирован в Core (это область elicitation methodology, см. research/11-elicitation-workflow.md).
Phase 1 — TZ import
1.1 Подписанный ТЗ
После итераций elicitation клиент подписывает TZ-2026-042:
# TZ-2026-042 — Login Flow для AcmeCorp Internal Tool
Дата подписания: 2026-05-03
Стороны: AcmeCorp + Kibertum
## §1. Цели
Сократить время входа сотрудников AcmeCorp в инструмент до <2 минут
от первого захода до полного доступа.
## §2. Функциональные требования
### ФТ-001. Регистрация по корпоративному email
Сотрудник регистрируется через email из домена @acmecorp.com.
Email вне домена — отказ с пояснением.
### ФТ-002. Двухфакторная аутентификация (TOTP)
После регистрации обязательная настройка 2FA через TOTP.
### ФТ-003. Восстановление доступа через корпоративный admin
При потере 2FA устройства — recovery через ticket в IT support.
## §3. Нефункциональные требования
### НФТ-001. Производительность
Login <2 секунд (p95).
### НФТ-002. Безопасность
- bcrypt cost-factor ≥ 12.
- Логи входов хранятся 1 год.
- Блокировка после 5 неудачных попыток за 15 минут.
### НФТ-003. Юрисдикция
Все данные в РФ (гос-контракты).
ТЗ подписан → immutable. Любые правки идут через ADAPT (см. Phase 2) или delta-TZ (см. Phase 8).
1.2 Substrate-native импорт
Пример команды для git+tausik substrate:
$ tausik req import-tz --order-id 042 --type initial \
--signed-date 2026-05-03 \
--source ./tz-input/TZ-2026-042.md
✓ Created acmecorp-login.req/tz/TZ-2026-042.md
✓ Branch created: feat/TZ-2026-042-initial
✓ AI-provenance recorded: import by tausik-import@v1.4
Для других substrate — эквивалентная operation импорта immutable документа с pin на substrate-native revision.
Phase 2 — ADAPT (двусторонняя интерпретация)
2.1 AI генерирует draft ADAPT
$ tausik req adapt-from-tz --tz TZ-2026-042
[claude-opus-4-7] Reading TZ...
[claude-opus-4-7] Generating Forward sections... 3 (по §2 ФТ-001/002/003 + §3 НФТ).
[claude-opus-4-7] Generating Backward findings... 6 candidates.
[claude-opus-4-7] Generated draft ADAPT-001.
Cost: 14,200 input + 3,800 output tokens
Time: 28s
2.2 Adversarial review backward записей
$ tausik req adversarial-review --adapt ADAPT-001
[gpt-4-turbo:critic] Reviewing backward findings...
[HIGH] B-001 (gap) "lost 2FA device recovery" дублирует ФТ-003 — это не gap,
а уточнение workflow. Reclassify как hidden-assumption.
[HIGH] Missed backward: ФТ-001 не описывает case-sensitivity email — gap.
[MEDIUM] B-004 (terminology) "сотрудник" — нужно определить через User.role.
[MEDIUM] B-006 (feasibility) "блокировка после 5 попыток" — за 15 минут на
одно IP, на один email, или на одну сессию? Уточнить с клиентом.
→ 4 findings: 2 high (reclassify, missed), 2 medium (clarification)
→ Block adapt-approve until resolved.
2.3 Iterative resolution
Архитектор корректирует Forward и Backward, AI re-генерирует. После 2 циклов adversarial:
- 7 backward записей (B-001..B-007).
- Все либо resolved (после ответа клиента), либо reclassified.
- Forward охватывает §2 + §3 ТЗ полностью.
2.4 Approved ADAPT
---
id: ADAPT-001
title: "Адаптация TZ-2026-042 — Login Flow AcmeCorp"
type: ADAPT
source-tz:
id: TZ-2026-042
signed-date: "2026-05-03"
signed-by-client: "AcmeCorp PM"
status: approved
approval:
client-signature:
signed-by: "Иванова А.А."
role: "Product Lead"
organization: "AcmeCorp"
signed-at: "2026-05-04T11:30:00Z"
architect-signature:
signed-by: "Петров П.П."
role: architect
signed-at: "2026-05-04T12:00:00Z"
generates-requirements: [BR-01, BR-02, SR-01, SR-02, SR-03, SR-04, SR-05, SR-06, SR-07]
generates-specs: [SPEC-UI-01, SPEC-API-01, SPEC-DATA-01, SPEC-SEC-01]
open-questions-count: 0
resolved-questions-count: 7
ai-provenance:
generated-by: "anthropic-claude-opus-4-7@2026-05-04"
prompt-template: "prompts/adapt-from-tz.md@v2.1"
human-edits: true
---
После approval ADAPT-001 — immutable.
Phase 3 — Декомпозиция в BR / SR / SPEC
3.1 Команда
$ tausik req decompose --adapt ADAPT-001
[claude-opus-4-7] Reading approved ADAPT...
[claude-opus-4-7] Generating BR candidates from Forward §1 (бизнес-цели)... 2 found.
[claude-opus-4-7] Generating SR candidates from Forward §2-§3... 7 found.
[claude-opus-4-7] Generating SPEC candidates (parallel axis)... 4 found.
[claude-opus-4-7] Generated draft artifacts.
3.2 Adversarial review артефактов
[gpt-4-turbo:critic] Reviewing draft BRs, SRs and SPECs...
[HIGH] BR-01 stakeholder поле пустое — кто owner business goal?
[HIGH] SR-05 говорит "bcrypt cost-factor 12" — это deployment detail,
должно быть в SPEC-SEC-01, не в SR.
[MEDIUM] НФТ-003 (юрисдикция) не отражено в data-classification SR-01.
[MEDIUM] SPEC-UI-01 не имеет accessibility-level — WCAG-AA минимум для
корпоративного инструмента.
→ 4 findings → fix → re-generate.
3.3 Финальный набор артефактов
acmecorp-login.req/
├── br/
│ ├── BR-01-self-service-registration.md
│ └── BR-02-secure-mfa.md
├── sr/
│ ├── SR-01-email-domain-validation.md (ФТ-001)
│ ├── SR-02-totp-enrollment.md (ФТ-002 setup)
│ ├── SR-03-totp-verification.md (ФТ-002 verify)
│ ├── SR-04-password-recovery-via-admin.md (ФТ-003)
│ ├── SR-05-rate-limiting-failed-logins.md (НФТ-002)
│ ├── SR-06-audit-logging.md (НФТ-002 audit)
│ └── SR-07-data-residency-ru.md (НФТ-003)
├── specs/
│ ├── ui/SPEC-UI-01-login-flow.md
│ ├── api/SPEC-API-01-auth.md
│ ├── data/SPEC-DATA-01-user-model.md
│ └── sec/SPEC-SEC-01-auth-policy.md
└── tz/
└── TZ-2026-042.md
3.4 Пример: SR-01 frontmatter
---
id: SR-01
title: "Валидация домена email при регистрации"
type: SR
status: approved
parent:
id: BR-01
source:
adapt: "ADAPT-001"
adapt-section: "Forward §2.1"
tz-section: "§2 ФТ-001"
constrained-by:
- "SPEC-API-01" # endpoint POST /auth/register
- "SPEC-DATA-01" # схема User
- "SPEC-SEC-01" # auth policy
data-classification:
contains-pii: true
data-residency: ["RU"]
retention-days: 365
compliance:
- { standard: "ФЗ-152", article: "ст.13.1" }
ai-provenance:
generated-by: "anthropic-claude-opus-4-7@2026-05-04"
prompt-template: "prompts/decompose-adapt.md@v2.1"
context-tokens: 12450
output-tokens: 320
human-edits: true
---
## Описание
Регистрация разрешена только если email принадлежит домену
`@acmecorp.com`. Остальные домены отклоняются с понятным пояснением.
## Поведение
- email НЕ из `@acmecorp.com` → 422 с body
`{"error":"email-domain-not-allowed", "allowed-domain":"acmecorp.com"}`.
[ADAPT-001 §2.1 Forward; TZ-2026-042 §2 ФТ-001]
- email из `@acmecorp.com` → стандартная регистрация (см. SPEC-API-01).
- whitelist хранится в SPEC-SEC-01.allowed-domains, расширяется без релиза.
- сравнение домена — case-insensitive (ADAPT-001 §2.1 Forward).
## Ограничения
- `*.acmecorp.com` subdomain — отдельное решение архитектора (не входит).
3.5 SPEC-API-01 (фрагмент)
---
id: SPEC-API-01
title: "REST API аутентификации"
type: SPEC-API
status: approved
source:
adapt: "ADAPT-001"
adapt-section: "Forward §2"
api-style: rest
api-version: "v1.0.0"
versioning-strategy: url-path
authentication: bearer-jwt
rate-limits:
- { endpoint: "POST /auth/login", limit: "5/15min/ip+email" }
contract-file:
format: openapi-3.1
location: "contracts/auth-api.yaml"
depends-on:
- "SPEC-DATA-01"
- "SPEC-SEC-01"
---
## Endpoints
### POST /auth/register
- body: `{"email": "<corp-email>", "password": "<strong>"}`
- 201 → `{"user_id": "<uuid>", "verified": false, "totp_setup": false}`
- 422 → invalid email или weak password
- 409 → email уже зарегистрирован
### POST /auth/login
- body: `{"email": "<corp-email>", "password": "<password>", "totp": "<6digits>"}`
- 200 → `{"access_token": "<jwt>", "expires_in": 3600}`
- 401 → invalid credentials
- 429 → rate limit (5/15min)
### POST /auth/totp-setup
- ... (см. SR-02)
## Error model
Единая структура: `{"error": "<code>", "details": {...}}`.
Phase 4 — TC generation (pos/neg pair)
4.1 Команда
$ tausik tc generate --requirement SR-01
[claude-opus-4-7] Analyzing SR-01...
[claude-opus-4-7] Identified 2 testable assertions:
- allowed domain → 201
- disallowed domain → 422
[claude-opus-4-7] Generating positive TCs... 2.
[claude-opus-4-7] Generating negative TCs... 2.
Generated:
tests/TC-001-sr01-allowed-domain-pos.md
tests/TC-002-sr01-allowed-domain-neg.md (case mismatch)
tests/TC-003-sr01-disallowed-domain-pos.md (правильно отказывает)
tests/TC-004-sr01-disallowed-domain-neg.md (плохо отказывает)
Pos/neg парность из Правила 4 RENAR Core: для каждого assertion’а в SR — 1 pos + 1 neg TC.
4.2 Пример TC-001 (позитивный)
---
id: TC-001
title: "Регистрация с разрешённым доменом — happy path"
type: system
status: ready
verifies:
- id: SR-01
requirement-version: "1.0"
negative: false
automation:
status: automated
location: "tests/auth/test_registration.py::test_allowed_domain_succeeds"
runner: pytest
---
## Given
- БД пуста; email alice@acmecorp.com не зарегистрирован.
## When
POST /auth/register {email: "alice@acmecorp.com", password: "ValidPass123!"}
## Then (Pass)
- status 201
- response body содержит {"user_id": "<uuid>", "verified": false, "totp_setup": false}
- в БД создан User(email="alice@acmecorp.com", verified=false, totp_setup=false)
- verification email отправлен (mock SES получил вызов с template_id)
## Fail criteria
- status ≠ 201
- response body содержит plaintext password или его hash
- User в БД с другим email (case mismatch)
- email верификации не отправлен
- в логах plaintext password
## Not in scope
- TOTP setup → TC-005 (verifies SR-02)
- Rate limiting → TC-009 (verifies SR-05)
4.3 Пример TC-004 (негативный)
---
id: TC-004
title: "Регистрация с неразрешённым доменом — отказ с пояснением"
type: system
status: ready
verifies:
- id: SR-01
requirement-version: "1.0"
negative: true
automation:
status: automated
location: "tests/auth/test_registration.py::test_disallowed_domain_rejected"
runner: pytest
---
## Given
- email "bob@gmail.com" (вне whitelist).
## When
POST /auth/register {email: "bob@gmail.com", password: "ValidPass123!"}
## Then (Pass)
- status 422
- response body == {"error": "email-domain-not-allowed", "allowed-domain": "acmecorp.com"}
- User в БД НЕ создан
- email НЕ отправлен
- в логах audit-запись о rejected attempt (для SR-06)
## Fail criteria
- status ≠ 422
- User создан в БД
- email отправлен (security leak)
- audit-запись отсутствует
Phase 5 — QG-1 approval
5.1 Все обязательные TC сгенерированы
После генерации TC для всех 7 SR — суммарно 26 TC (pos+neg + extra negatives для SR-05, SR-06).
5.2 QG-1 promote BR-01 → approved
$ tausik req promote --to approved --requirement BR-01
QG-1 conditions:
✓ source.adapt = ADAPT-001 (status: approved)
✓ All children SR в status >= draft
✓ adversarial-review passed (cycle 2 of 2)
✓ TCs generated для всех priority=must children
✓ pos/neg pair coverage = 100% (26/26 TC паренные)
✓ All assertions имеют citations к ADAPT-001
[architect approves]
✓ BR-01 status: draft → approved
✓ All children SR cascade: draft → approved
✓ All TCs: draft → ready
Phase 6 — Реализация
6.1 Создание задач (TR)
$ tausik req sync-tasks --substrate tausik
Создаю TR:
TR-101: Implement domain validation (SR-01) — assignee: @backend-dev
TR-102: Implement registration form (SPEC-UI-01) — assignee: @frontend-dev
TR-103: Implement TOTP enrollment (SR-02) — assignee: @backend-dev
... 7 TR total
Каждая TR:
- parent.id: <SR>
- implements-spec: [<relevant SPEC>]
- QG-0 готов (Goal+AC из SR.поведение + SPEC contracts)
6.2 Разработчик берёт TR-101
$ tausik task start TR-101
[QG-0] Verifying task readiness...
✓ Goal exists (from SR-01)
✓ AC list (4 items из SR-01.поведение)
✓ parent.id: SR-01 (resolves; status=approved)
✓ implements-spec: [SPEC-API-01, SPEC-SEC-01]
✓ Negative scenario in AC: yes (case-mismatch test)
✓ Threat surface: low (input validation)
Task ready. Starting work session.
6.3 Реализация (фрагмент)
# acmecorp-login.src/src/auth/registration.py
from fastapi import HTTPException
from config import settings # allowed-domains из SPEC-SEC-01
def validate_email_domain(email: str) -> None:
domain = email.split("@", 1)[-1].lower()
if domain not in settings.AUTH_ALLOWED_DOMAINS:
raise HTTPException(
status_code=422,
detail={
"error": "email-domain-not-allowed",
"allowed-domain": settings.AUTH_ALLOWED_DOMAINS[0],
},
)
# acmecorp-login.src/tests/auth/test_registration.py
def test_allowed_domain_succeeds(client, db, mock_ses):
r = client.post("/auth/register",
json={"email": "alice@acmecorp.com", "password": "ValidPass123!"})
assert r.status_code == 201
assert "user_id" in r.json()
user = db.query(User).filter_by(email="alice@acmecorp.com").one()
assert user.verified is False
mock_ses.send_email.assert_called_once_with(
template_id="verification-email",
to_email="alice@acmecorp.com",
)
def test_disallowed_domain_rejected(client, db):
r = client.post("/auth/register",
json={"email": "bob@gmail.com", "password": "ValidPass123!"})
assert r.status_code == 422
assert r.json() == {
"error": "email-domain-not-allowed",
"allowed-domain": "acmecorp.com",
}
assert db.query(User).count() == 0
6.4 Substrate-native validation
При попытке коммитить — substrate-нативный hook проверяет SR-ссылки в TR и наличие негативного TC:
[pre-commit] Verifying TR linkage:
✓ TR-101 has parent.id: SR-01 (exists, approved)
✓ TR-101 implements-spec: [SPEC-API-01, SPEC-SEC-01] (exist, approved)
[pre-commit] Verifying negative TC presence:
✓ SR-01.verified-by includes TC-002, TC-004 (negative)
✓ Commit allowed
Phase 7 — QG-2 verified-by-TC
7.1 CI запускает TC
[CI] pytest acmecorp-login.src/tests/auth/test_registration.py
test_allowed_domain_succeeds ............... PASSED
test_disallowed_domain_rejected ............ PASSED
[CI] Bot обновляет last-run в TC файлах:
TC-001: last-run.result = pass, requirement-version = 1.0
TC-002: last-run.result = pass, requirement-version = 1.0
TC-003: last-run.result = pass, requirement-version = 1.0
TC-004: last-run.result = pass, requirement-version = 1.0
7.2 Spot-check (Правило 5 Core)
Раз в спринт инженер вручную запускает 5 случайных passing TC и сверяет фактический результат с SR:
$ tausik tc spot-check --sprint current --count 5
Selected (random): TC-001, TC-008, TC-012, TC-019, TC-024.
Running manually...
TC-001: pass (matches SR-01 expected)
TC-008: pass (matches SR-02)
TC-012: pass (matches SR-03)
TC-019: pass (matches SR-05)
TC-024: pass (matches SR-06)
✓ Spot-check passed: 5/5.
7.3 Promote SR-01 → verified
$ tausik req promote --to verified --requirement SR-01
QG-2 verified-by-TC:
✓ SR-01 ссылается на approved ADAPT-001
✓ Pos TC TC-001, TC-003: pass
✓ Neg TC TC-002, TC-004: pass
✓ TC проверяют поведение (не реализацию)
✓ Spot-check passed для current sprint
✓ requirement-version (1.0) pinned
[architect approves]
✓ SR-01 status: approved → verified
✓ COVERAGE.md updated
Phase 8 — Delta-TZ
8.1 Клиент через неделю
# TZ-2026-051 — Дополнение к TZ-2026-042
Базовый: TZ-2026-042
## §2 (изменение)
### ФТ-001 (расширение)
Дополнительно разрешить @subsidiary.acmecorp.com (дочерняя компания).
Whitelist расширяется до 2 доменов.
8.2 Delta-ADAPT
$ tausik req adapt-from-tz --tz TZ-2026-051 --parent-adapt ADAPT-001
[claude-opus-4-7] Reading delta-TZ + parent ADAPT-001...
[claude-opus-4-7] Generating delta Forward... 1 section (§2.1 extension).
[claude-opus-4-7] Generating delta backward... 1 finding:
B-008 (scope): subsidiary email — какой регистр case-sensitivity?
Тот же что и main, или явно разный?
Generated draft: ADAPT-001-delta-1.
После 1 итерации с клиентом — ADAPT-001-delta-1 → approved.
8.3 Impact analysis
$ tausik req impact --delta TZ-2026-051
Impact Analysis:
Affected BR: BR-01 (расширяется scope)
Affected SR:
- SR-01: уточнение (whitelist 1 → 2 domains)
- status downgrade: verified → approved (требует rerun TC)
Affected TC:
- TC-001..TC-004: requirement-version 1.0 → 1.1 (re-pin после updates)
- 2 новых TC нужны: subsidiary domain (pos + neg)
Affected TR:
- TR-101: completed; нужна new TR-115 для расширения validation
Affected SPEC:
- SPEC-SEC-01: allowed-domains [acmecorp.com] → [acmecorp.com, subsidiary.acmecorp.com]
8.4 Apply delta
Архитектор открывает изменения с маркером [delta:TZ-2026-051]. AI обновляет SR-01 (расширяет whitelist), генерирует 2 новых TC. Реализация в TR-115. CI прогоняет TC, bot обновляет last-run. После spot-check — SR-01 v1.1 → verified снова.
Phase 9 — QG-4 acceptance
9.1 Через 4 недели после release
$ tausik req evaluate start --release v1.0
Measurement window: 4 weeks since 2026-05-15
BR-01: Самостоятельная регистрация
KPI: Time-to-first-login
Target: < 2 minutes (P95)
Actual: 1.4 minutes (P95)
Achievement: 143% (beat target)
BR-02: Secure MFA
KPI: % users with 2FA enabled within 7 days
Target: ≥ 95%
Actual: 97%
Achievement: 102%
9.2 QG-4 report + adversarial
AI генерирует acceptance report. Adversarial critic находит: «recovery через admin не покрыт TC, верифицирующим full flow с tickets». Архитектор соглашается → создаёт mini-delta для добавления acceptance TC.
9.3 Sign-off
После закрытия findings клиент подписывает acceptance. BR → status accepted.
acmecorp-login.req/
├── QG-4-REPORT-v1.0.md # архив отчёта
└── lessons/2026-Q2.md # lessons learned
Финальные артефакты
acmecorp-login.req/
├── adapt/
│ ├── ADAPT-001-main.md (status: frozen)
│ └── ADAPT-001-delta-1.md (status: frozen)
├── br/
│ ├── BR-01-self-service-registration.md (status: accepted)
│ └── BR-02-secure-mfa.md (status: accepted)
├── sr/
│ ├── SR-01-email-domain-validation.md (v1.1, verified)
│ ├── SR-02-totp-enrollment.md (v1.0, verified)
│ ├── SR-03-totp-verification.md (v1.0, verified)
│ ├── SR-04-password-recovery-via-admin.md (v1.0, verified)
│ ├── SR-05-rate-limiting-failed-logins.md (v1.0, verified)
│ ├── SR-06-audit-logging.md (v1.0, verified)
│ └── SR-07-data-residency-ru.md (v1.0, verified)
├── specs/
│ ├── ui/SPEC-UI-01-login-flow.md (verified)
│ ├── api/SPEC-API-01-auth.md (verified)
│ ├── data/SPEC-DATA-01-user-model.md (verified)
│ └── sec/SPEC-SEC-01-auth-policy.md (verified, v1.1)
├── tests/
│ └── TC-001..TC-028 (28 TC, 100% passing)
├── tz/
│ ├── TZ-2026-042.md (initial, immutable)
│ └── TZ-2026-051.md (delta, immutable)
├── elicitation/ (Phase 0 артефакты)
├── lessons/2026-Q2.md (Phase 9 lessons)
└── QG-4-REPORT-v1.0.md (acceptance report)
Метрики проекта
После accepted release:
| Метрика | Значение |
|---|---|
| RDLT (TZ signed → all SR verified) | 11 days |
| Coverage Velocity | 100% за 2 sprint’а |
| Hallucination Rate (детектированных) | 0% |
| Adversarial findings caught (cycle 1) | 4 high + 2 medium |
| Test-spec drift на delta-ТЗ | 0% |
| Acceptance disputes | 0 (1 finding, resolved before sign-off) |
| Cost per BR | $0.46 (gen) + $0.18 (critic) = $0.64 |
| Total AI cost | ~$8.50 |
| BRs accepted | 2/2 |
| Дней до accept | 35 |
Что показывает этот пример
- Прозрачность — каждый артефакт имеет provenance, каждый переход — gate с явными условиями.
- Скорость — декомпозиция approved ADAPT — 28 секунд + 2 цикла adversarial.
- Trace — от строки в ТЗ до passing TC за 2 клика (substrate-агрегированный запрос).
- Delta-ТЗ — затронутые SR/SPEC/TC/TR — автоматически вычисляются.
- Закрытие петли — QG-4 связывает back к business outcomes (KPI achievement).
- AI-нативно — критик и генератор — разные модели (изоляция); spot-check ловит то, что автоматика не видит.
Что дальше
- Переход с legacy подхода (без ADAPT, без SPEC, без adversarial) — 02-transition-guide.md.
- Git как substrate с подробностями — 03-tool-guide-git.md.
- Raven как substrate — 04-tool-guide-raven.md.
- Сравнение с SAFe / BABOK / ISO 29148 — 05-safe-comparison.md.
- Compliance mapping (GDPR / ФЗ-152 / AI Act) — 06-compliance.md.
- Failure modes — 07-failure-modes.md.
Walkthrough RENAR 1.0-draft — renar.tech