Wiki 🔍 Search
QIIUB · Team Scaling System

How we go from 3 to 7+ developers without breaking the codebase.

A complete operating model for the team — three foundational questions, one set of tools, and a clear path from where we are today to where we're going. The model is adopted and rolling out in phases. Read it before you write your first line.

For: the QIIUB engineering team Read time: ~10 minutes Status: adopted · rolling out in phases (see below)
Where this stands · 2026-06-08

Adopted, and rolling out in phases.

This is no longer a hypothetical. The model below is the team's operating system, ratified across docs/adr/ (ADR-0083–0096). Most of the foundation is live; the rest is rolling out. Here's the honest split, so you can tell the vision from what works today.

Live today

  • Root CLAUDE.md + the precedence cascade · gated-path Hard Stops
  • .github/CODEOWNERS · Mike + JJ as global Secondary Owner
  • cascade-guards.yml CI check · runs on every PR
  • 4 typed issue templates + PR template · GHES Issues live
  • Task source of truth = GHES Issues + Project #5 · ratified in ADR-0096 (D7)
  • T1–T5 cascade-behavior tests · validated and recorded

Rolling out

  • Branch protection on main · the final enforcement step
  • docs/lookbook.md · canonical-example seed (path already pre-gated)
  • Open Notion tasks → GHES Issues import (ADR-0096 P2)
  • Retiring the legacy Notion task tooling (ADR-0096 P3)
  • Agent review (pr-review-toolkit) as a required CI gate · today it's a pre-commit discipline
  • QA Phase validation pass · onboarding ritual doc
00 · Quick glossary

Twelve terms · so the rest reads fast.

If you've worked on small teams, some of these will be new. The full definitions live in docs/GLOSSARY.md.

Cascade · the 4-level guide structure every Claude reads: root CLAUDE.md → sub-CLAUDE.md per area → Lookbook → Onboarding.
Drift · when code diverges from the cascade without an explicit guide update. The thing the system catches.
Gated path · a file/dir in CODEOWNERS that needs owner approval. QIIUB gates ~8 core categories (plus a few governance/ops files). Everything else flows freely.
Lookbook · single doc mapping "I need to build X" to "look at this canonical file." Pattern matching against real code.
Manifest · the PR template section declaring new endpoints / entities / migrations / ADRs / breaking changes. "None × 5" = light review.
sub-CLAUDE.md · area-specific CLAUDE.md (e.g., Features/Loyalty/CLAUDE.md). Auto-loaded by Claude in that folder.
qa-fix · PR title prefix for trivial fixes that skip issue + manifest. Six criteria: 1 sentence, 1 file, < 50 lines, not in gated paths.
qa-pass-1 · label for issues filed during QA Phase. Retired at QA → Flow transition; everything gets re-labeled.
Trust boundary · the line beyond which governance can't be bypassed. CI is the trust boundary; pre-commit hooks are local convenience only.
Bus factor · how many people have to be hit by a bus before the team's blocked. JJ as global Secondary Owner takes it from 1 (Mike) to 2 — now wired in CODEOWNERS.
Load-bearing · code/decisions that lots of other things depend on. Schemas, ADRs, root CLAUDE.md · changes here ripple far.
Pull-based assignment · devs grab tasks from the ready queue themselves vs. being assigned. Default for 95% of work; not a prohibition.
01 · The why

Coherence is what we lose first when we grow.

QIIUB today is unusually coherent — every endpoint follows the same pattern, every screen uses the same components, every ADR is consistent. This is the project's biggest asset. It's also the one most easily lost when the team expands.

Without a shared system

  • Seven developers, seven implicit styles · "the QIIUB way" becomes unclear
  • Locale keys missing in ES because the dev only edited EN
  • Some screens use Drawers, others Modals, for the same form size
  • Same bug gets filed three times because there's no clear owner
  • PRs reviewed for surface bugs, not for pattern drift
  • New devs cannot tell what is correct without asking
  • The codebase quietly looks like 25 people built it

With the system below

  • One canonical way to do common tasks · Lookbook + cascade
  • Locale parity check in CI catches missing keys before merge
  • Component rules are explicit · DataTable, Drawer, Modal each have a use case
  • Every issue has an area label · owner is obvious
  • Reviews focus on drift + correctness, not nits CI already catches
  • Dev 7's code is indistinguishable from Dev 1's
  • The codebase looks like one team built it, regardless of size
Coherence cannot be enforced by review alone — review is too slow and too easily eroded. The system below encodes coherence into the inputs every developer (and every AI assistant) reads before generating any code.
02 · The framework

Any multi-developer system must answer three questions.

Knowledge, Ownership, Flow. Each one fits into ~30 seconds of explanation. Together they form the operating model.

1
Knowledge

How does every Claude reach the same answer?

A four-level cascade of guides every Claude reads before generating code. CLAUDE.md → sub-CLAUDE.md per area → Lookbook → Onboarding pass. Same patterns, every laptop.

2
Ownership

Who can approve what change?

Gated paths in CODEOWNERS need owner sign-off — Mike, or JJ as Secondary Owner. Everything else (95% of PRs) needs only 1 approval from any teammate. Enforced server-side by CI + (soon) branch protection.

3
Flow

How does work move from idea to merged code?

Seven stages: idea → spec → issue → branch → PR → review → post-merge. Each stage has clear conventions, templates, and CI checks. The path is predictable for everyone.

95%
PRs need no Mike
1 approval from any teammate is enough
8
Gated paths
Only the dangerous 5% need owner review
7
Flow stages
Same path for every piece of work
~24h
Normal PR SLA
From ready-for-review to merged
03 · Question 1 · Knowledge

One guide, four levels, every Claude reads it.

When seven developers each work with their own Claude, every Claude reads only the code it can see and infers its own conventions. The result: seven implicit styles. The fix: a cascade of guides everyone (human and AI) reads first.

1
CLAUDE.md root
Universal rules: nullable types, async/await, FastEndpoints, EF Core, security checklist, brand colors, naming. Applies everywhere. Already exists in QIIUB and is excellent.
When read Always. Every Claude session loads it at start.
2
sub-CLAUDE.md per area
Mini-CLAUDE.md inside each feature folder. ADRs relevant to the area, key entities, gotchas, owner, canonical templates. ~50-150 lines each.
When read Auto-loaded when Claude works inside that folder.
3
Lookbook
A single doc at docs/lookbook.md mapping "I need to build X" to "look at this file." Pattern matching against real, working examples in the repo.
When read Referenced from sub-CLAUDE.md when creating something new.
4
Onboarding pass
Two-day mentor-led ritual when a new dev joins. Use Claude Code's native onboarding-guide generator to seed the Day-1 codebase tour, then walk through 3 pre-selected ADRs, tour the Lookbook, ship a dummy PR. Then real work unlocks. (Tool + ritual are complementary: tool = understand existing code; ritual = process, culture, dummy-PR gate.)
When read Once per developer, before they touch real code.
Drift correction is the real multiplier. When Mike sees one dev's Claude drift, he updates ONE file in the guide. The next session, every Claude on every laptop is aligned. One correction · seven minds updated.
04 · Question 2 · Ownership

Eight gated paths. Everything else flows freely.

The biggest mistake a growing team makes is reviewing everything as if it were equally dangerous. We don't. Only eight paths in the repo carry permanent consequences if a wrong change merges — those need owner approval. Everything else needs one teammate's eyes, no more.

The 8 paths that need owner approval

PathOwnerWhy it's gated
/src/QIIUB.Domain/Entities/ Mike A new entity is permanent schema. Mistakes propagate to migrations, sync, RLS, and offline POS clients.
/src/QIIUB.Infrastructure/Migrations/ Mike Migrations are irreversible once shipped. Offline clients may run an old schema mid-deploy.
/docs/adr/ Mike + JJ ADRs are decisions everyone inherits. A bad ADR shapes months of work in the wrong direction.
/CLAUDE.md Mike + JJ Affects every Claude session on every dev's laptop. Wrong rule = drift everywhere.
/docs/lookbook.md Mike + JJ The canonical examples reference. A wrong entry teaches everyone the wrong pattern.
/packages/qiiub-ui/src/styles/tokens.css Mike + JJ (+ Designer) One token change ripples across 100+ screens. Color, spacing, font shifts affect every page at once.
/.github/workflows/ Mike + JJ Breaking CI breaks the whole team's ability to merge. Fragile and global.
/.github/CODEOWNERS Mike + JJ Self-gating: the file that defines gates cannot change without owner review. JJ as co-owner exists so Mike's own CODEOWNERS PRs can be approved when he's out.

The live .github/CODEOWNERS is the authoritative list and has grown beyond these eight as the repo matured — it also gates DESIGN-SYSTEM.md, the design-token assets, the doctor / smoke-test scripts, and the Auth / Identity / Invitations feature folders. Schema (Entities/, Migrations/) and auth stay Mike-only; everywhere else Mike and JJ co-own.

Everything else · the 95%

95%
New endpoints in existing folders. New React components. Bug fixes. New tests. Locale keys. Refactors that don't touch the gated set. 1 approval from any teammate, CI green, merge. No Mike, no waiting on a specific person, no ceremony.

How it's enforced (this matters)

The gates are server-side: the cascade-guards.yml CI workflow runs on every PR and checks the gated paths against the manifest (live); CODEOWNERS auto-requests the right reviewer (live); branch protection on main — the final activation step — hard-blocks the merge button until both pass. No client-side pre-commit hook controls governance. Hooks can be bypassed with --no-verify, so they're not trustworthy as gates. CI is the trust boundary.

How it scales

As the project grows, more paths join the gated set — but only at real business milestones, not arbitrarily. First pilot live? Add Sync Engine + Payments + Auth. Three merchants in production? Move to a primary+secondary owner model per area. Multi-region rollout? Full release management. The model tightens with the stakes, never ahead of them.

05 · Question 3 · Flow

Seven stages. Same path for every piece of work.

From "someone has an idea" to "it's merged in main" — seven concrete steps with clear tooling at each. No mystery about where work is or who owns the next move.

1
Idea
Notion · upstream
2
Spec
docs/superpowers/specs/
3
Issue
GHES Issues · 4 templates
4
Branch
type/author/topic
5
PR
template + CI checks
6
Review · merge
CODEOWNERS + squash
7
Post-merge
auto · 95% no human action
Ratified · ADR-0096 (D7). The task source of truth is GHES Issues + the QIIUB Engineering Project; Notion is upstream product / roadmap only. Open Notion tasks migrate to Issues in P2; the legacy Notion task tooling retires in P3. (On GHES 3.20 the board's close→Done step is currently manual.)

Day-to-day · the actual mechanics

Issue templates · 4

Each issue uses one of four templates:

  • type:feature · requires approved spec, has acceptance criteria
  • type:bug · has reproduction steps, severity
  • type:tech-debt · explains the debt + impact
  • type:task · catch-all for chore, docs, infra

Branch names · Conventional Commits set

Branch prefix = PR-title type = commit type. Drawn from the CC standard set (feat · fix · chore · docs · refactor · test · build · ci · perf) plus spec/ and hotfix/ as local extensions. Commit subject ≤ 50 chars.

  • feat/mgandia/sales-report-by-category
  • fix/jflores/sync-deadlock
  • chore/mgandia/upgrade-fastendpoints
  • docs/mgandia/adr-0083
  • spec/jflores/customer-notes

The trivial-fix exception

Some changes are so small they don't need an issue or a manifest. Six criteria: 1 sentence describable, 1 file, < 50 lines, not in src/QIIUB.*, not in docs/adr/, not in CODEOWNERS gated paths. Examples: locale key typo, missing aria-label, hardcoded hex → token, missing test. Title prefix qa-fix:. The PR is the tracking. CI validates the criteria — you can't lie your way past them.

Merge strategy · squash and merge (only)

Every PR squashes to one commit on main. The PR title + body becomes the commit message. Clean linear history. Easy reverts. The full PR history (every individual commit) is preserved in GHES for context. No merge commits, no rebase merges — one button, one rule.

06 · Before all of the above

QA Phase first · 2-3 weeks of validating what already exists.

Before development with the full team starts, the three available developers (Manager + 2 new hires) spend 2-3 weeks mechanically validating the existing codebase. The point: build shared mental model, find gaps, and exit the phase with a triaged backlog — not to "do new work."

What QA Phase IS

  • ▸ Mechanical validation: every screen, every endpoint, every flow
  • ▸ Documenting bugs, gaps vs mockup, UX inconsistencies
  • ▸ Fixing trivial issues on the spot (typos, missing locales)
  • ▸ Building shared mental model of how QIIUB behaves end-to-end
  • ▸ Producing a triaged backlog labeled qa-pass-1

What QA Phase IS NOT

  • × Feature development of any kind
  • × Refactoring "while we're here"
  • × Schema changes, new entities, new migrations
  • × New endpoints, new screens, new ADRs
  • × Anything touching src/QIIUB.* beyond cosmetic fixes

The decision rule for QA findings · all six must be true

A QA finding can be fixed on the spot (with qa-fix: prefix) only if:
1 · Describable in one sentence  ·  2 · Touches exactly one file  ·  3 · Under 50 lines changed
4 · NOT under src/QIIUB.*  ·  5 · NOT under docs/adr/  ·  6 · NOT matched by any CODEOWNERS gated path

Otherwise → file an issue with qa-pass-1 label. The triage at end of QA Phase handles it.

07 · What changes for you

For each role · the practical impact.

If you're a PM, dev, or QA, here's the day-to-day reality with this system. Skip to your row.

PM

Product / Design

  • Write specs in docs/superpowers/specs/ using the light template (~1 page, 7 sections)
  • Review spec PRs before they become issues
  • Maintain the Notion → spec handoff for research-team input
  • Co-own UI design system tokens (with Mike)
  • Run the Monday triage with Mike (~20 min)
D

Developers (you)

  • Check status:ready queue, self-assign, start coding
  • Use branch naming type/author/topic
  • Fill the PR template (manifest + self-review checklist)
  • Your Claude reads the cascade automatically — write code, not docs about how to write code
  • Review teammates' PRs (1 approval = merge)
  • Open a spec PR if your feature is non-trivial — every dev can author specs
QA

QA / Test

  • Run the QA Phase pass during the first 2-3 weeks
  • File qa-pass-1 issues for anything beyond trivial fixes
  • Write integration tests in parallel with developers, not after
  • Cross-merchant isolation tests are mandatory for every feature
  • Mark sortable column behavior + i18n parity in test plans
M

Mike

  • Approve gated path PRs (entities, migrations, ADRs, tokens, workflows)
  • Spend ~30 sec per PR on the gated 5%; nothing on the 95%
  • Friday spot-check of 3 random merged PRs (drift detection)
  • Quarterly self-check (~45 min) — verify the system is still fitting
  • Update the cascade when drift is observed · one file = aligns everyone
08 · What a normal day looks like

Monday morning · a developer's actual workflow.

No process matters until you can describe it as a normal day. Here's yours:

1
09:00 AST
Pull main, open GHES Projects board
You're on main, fresh. Open the GHES Projects board, filter to your area + status:ready. Pick the next issue based on your capacity + priority. Self-assign.
2
09:10 AST
Branch + Claude starts
Create feat/yourname/topic branch from main (Conventional Commits prefix). Open Claude Code in the area folder. Claude auto-loads CLAUDE.md root + the sub-CLAUDE.md for your area. You're working against the same patterns Mike uses.
3
09:15–14:00
Build the feature
You write code. Claude pattern-matches against the Lookbook canonical examples for the kind of work you're doing. You run tests locally, iterate. If a CI check would catch something (locale parity, design discipline), Husky lint-staged catches it locally first as fast-feedback — but if you push past it with --no-verify, CI catches it anyway. The trust boundary is server-side.
4
14:30 AST
Open PR
Push branch, open PR using the template. Fill the Summary, the Linked section (Fixes #234), and the manifest (likely all "None" for a regular feature). Self-review checklist. Convert from Draft to Ready for review. GHES auto-requests reviewers based on CODEOWNERS — almost certainly NOT Mike, since you didn't touch a gated path.
5
~14:45 AST · ~2-3 min
Agent review pass · pr-review-toolkit
Before you commit, you run the pr-review-toolkit agents (code-reviewer, code-simplifier, silent-failure-hunter, type-design-analyzer) — mandated by CLAUDE.md. They check drift vs CLAUDE.md, catch unused code, find swallowed errors, scan type safety. You fix what they flag before a human ever opens the PR. Today this is a pre-commit discipline; wiring it as a required CI gate is a planned rollout step.
6
~16:00 AST
Human reviewer takes ~5 min
A teammate runs the 2-pass human review (the agent already handled drift + correctness): judgment (does this solve the right problem? does it fit the spec/issue intent?) + coherence (does it fit alongside neighboring code in this area?). Comments use prefixes: blocking:, nit:, question:, suggestion:. You know what needs to change vs what's optional.
7
~16:45 AST
CI green · you click merge
CI runs all required checks (typecheck, lint, test, build, migration-safety, locale-parity, design-discipline, cross-tenant-isolation, manifest-present). All green. You click Squash & Merge. The branch auto-deletes. The linked issue auto-closes via Closes #N. (Moving its Project board card to Done is currently manual — GHES 3.20's built-in close→Done doesn't fire yet.)
8
~16:50 AST · ~5 min
Post-merge CI on main
The same CI suite runs a second time, this time against main itself (not your PR snapshot). Catches semantic conflicts: two PRs each green in isolation that break together. If post-merge CI fails, #qiiub-devs is alerted within minutes — you can revert your merge in one command (squash makes every merge one revertable commit) and the team continues. Detection + revert-first norm: restoring green is the priority; diagnosis is a follow-up PR.
9
later
No human action required (95% of cases).
Unless your PR was big, breaking, or shipped a new module, you don't need to post anywhere or notify anyone. GHES notifications already reached author + reviewers. The system handles the rest.
Your involvement with "the process" is opening a PR with the template filled out, and reviewing a teammate's PR. Everything else — the cascade, the CI checks, the auto-routing, the squash, the post-merge — runs without you thinking about it.
09 · How it grows with us

The system tightens at business milestones, not by calendar.

Today we're at "dev iteration" — no paying customers yet, so the gates are minimal. As QIIUB acquires real customers, more paths join the gated list. The triggers are business events, not arbitrary dates.

Dev iteration You are here · no customers
8 gated paths · 95% free flow · 1 approval from any teammate · Mike on all gated paths · CI checks warning-only → required after 2 weeks stable · pull-based assignment
First pilot live Milestone +1 · 1 paying customer
Add Sync Engine + Payments + Auth to gated · activate hotfix: branch type and process · mandatory integration test on every gated PR · monthly retro begins
3–5 merchants Milestone +2 · real revenue
Add Multi-tenant Core + Inventory + Loyalty to gated · primary+secondary owner per area · backup activates after 24h · auto-label 2-approval workflow activates · tighter long-running branch tolerance
Multi-region scale Milestone +3 · 10+ merchants
All feature folders gated · release branches + formal change management · ADR review committee (2 reviewers) · Mike is escalation, not gatekeeper

Note the inversion: today Mike is on every gated path. At scale he's on almost nothing day-to-day — area owners do it. The system was designed from day one so this scaling works without re-architecting.

10 · The foundation · mostly shipped

Phase 0 · the load-bearing minimum.

Phase 0 lays the load-bearing minimum before the team builds new features. Most of it is live: ✓ shipped — root CLAUDE.md updates, .github/CODEOWNERS, cascade-guards.yml, the 4 issue templates + PR template, and the T1–T5 cascade tests. ◷ still rolling out — branch protection on main, the Lookbook seed, the onboarding-ritual doc, and the label taxonomy. After this, QA Phase runs with the cascade already operational, and full Flow kicks in at QA's Definition of Done.

Empirical tests T1-T5

Validate the actual behavior of nested CLAUDE.md files in Claude Code. Without these, sub-CLAUDE.md design is betting on assumptions. ~1-2 hours of Mike's time.

Root CLAUDE.md updates

Precedence rules · hard-stop reminders · versioning header. Already excellent; small additions only.

CODEOWNERS ✓ live

.github/CODEOWNERS is live — Mike + JJ co-own, with schema and auth Mike-only. Still pending: branch protection on main (Require Code Owner reviews · approval from someone other than the last pusher · Include administrators).

cascade-guards.yml

The single CI workflow that enforces the gated paths server-side. Cannot be bypassed locally. Migration safety, locale parity, design discipline, cross-tenant isolation, manifest presence.

Lookbook seed

One canonical example per common task: endpoint, page, test, ADR. Links to real files in the repo. New devs pattern-match against these.

Issue + PR templates ✓ live

Four issue templates (feature, bug, tech-debt, task) + PR template, live on main. The label taxonomy (type: / priority: / area:) is still being set up as part of ADR-0096 P2.

Onboarding pass document

Two-day mentor-led ritual. For Dev 2 and Dev 3 immediately; refined for Devs 4–7 as they join.

Operational cadence calendar

Recurring tasks (GHES Issues / calendar) for Monday triage, Friday spot-check, monthly milestone check, quarterly self-check. ~1 hour/month of Mike-discipline overhead, sustainable.

11 · FAQ from skeptical engineers

The objections you'd raise (and the answers).

Isn't this going to slow us down?
No. Only 5% of PRs hit a gated path. The other 95% need 1 approval from any teammate — same as having no gates at all, just with a clearer routing. The CI checks add seconds, not minutes, and catch real problems before review eats them. The system removes the slowdown of "wait, who reviews this?" because the answer is automatic.
Why is Mike on every gated path? That's a bottleneck.
It is — by design, today, while the team is 3 devs. The model explicitly inverts as we grow: at 3-5 merchants in prod, ownership splits into primary + secondary per area, and Mike becomes escalation. The bottleneck is intentional now because schema/ADR/CLAUDE.md mistakes at 3 devs are still cheap to fix; at 10+ merchants they're expensive. The model trades velocity for safety, and the trade reverses as the team and stakes grow.
What if I disagree with a reviewer?
Discuss in the PR. If you can't resolve in 24 hours, ping in Slack/Notion. If still stuck, Mike decides — in dev-phase, he's the technical escalation. Comment prefixes (blocking:, nit:, suggestion:) make it clear what's a real disagreement vs a preference. Most of what becomes a fight is actually a nit; the prefix forces clarity.
Why squash-merge only? I want my commits preserved.
Your individual commit history is preserved in GHES forever in the PR view. The squash gives main a clean, linear history where each commit is one logical change, easy to revert, easy to read in git log. The trade-off is small for the dev (you can still see your work-in-progress commits in the PR) and large for the codebase (no "WIP" or "fix typo" commits cluttering main).
What happens if I need to change something that touches a gated path?
You write the PR like normal. GHES auto-requests Mike's review based on CODEOWNERS. Mike reviews the gated bit (usually ~5 minutes — he's looking at ~30 lines of schema, not the whole PR). You get approval, CI green, merge. The other parts of your PR are reviewed by any teammate in parallel. The gated review doesn't block the rest; both run concurrently.
Why all the CI checks? Won't my PR fail for stupid reasons?
Each check exists because of a specific, real failure mode the team has seen or anticipates: locale-parity prevents broken EN/ES screens, design-discipline prevents hardcoded hex bypassing our tokens, cross-tenant-isolation prevents the single most expensive bug class in multi-tenant POS, migration-safety prevents destructive schema changes that break offline clients. New checks ship as warning-only for 2 weeks before they're required — if a check is flaky, we don't promote it. The team has veto over CI policy.
I work with Cursor / Copilot, not Claude Code. Does this still work for me?
The cascade auto-loading is specific to Claude Code. With other AI tools or no AI, you read the relevant CLAUDE.md files manually before working — same content, just no auto-load. The CI checks and CODEOWNERS work the same regardless of editor. We're standardizing on Claude Code for the team to keep the cascade tooling consistent; if you prefer another tool for personal experiments, fine, but team work goes through Claude Code's cascade.
What if I find a bug while implementing a feature, but it's in a different area?
File a separate type:bug issue. Don't fix it inside your feature PR — that's scope creep, makes the PR harder to review, and pollutes the squash commit. The rule is: a PR does one thing. If you found 3 bugs while building 1 feature, that's 3 follow-up issues, not 4 things squashed into your feature merge.
What if I think the rules are wrong?
Open a PR modifying CLAUDE.md, sub-CLAUDE.md, or the Lookbook with your proposed change. CODEOWNERS will route it to Mike. The system improves by being edited, not by being argued about. If your rule change makes 7 Claudes write better code, it ships. The whole point of the cascade is that one edit aligns everyone — so good edits are high-leverage.

Where we go from here.

The model is adopted and rolling out. What we still need from each of you:

Read this whole doc

Ask questions in the team channel. Push back. The system is meant to be edited, not memorized.

Confirm your GHES handle

So Mike can wire CODEOWNERS correctly when Phase 0 ships.

Pick your areas of interest

Which functional areas (Auth, Loyalty, Inventory, etc.) do you want to own primarily?

Be ready for QA Phase

2-3 weeks of mechanical validation comes first. Bring your skepticism — that's what this phase is for.