Quick Start Preparation: Turn Discovery into a Scaffolding-Ready Package
Why this chapter exists
Chapter 1 produced the raw customization artifacts.
This chapter prepares them for deterministic scaffolding.
The goal here is not to build the repo yet. The goal is to make sure Claude Code can take the discovery output and generate a strong initial repo state with:
- structure
- standards
- plans
- agent roles
- starter fixtures
- starter tests
- validation scripts
- durable documentation
Think of this chapter as the assembly step between discovery and generation.
Inputs required from Chapter 1
These must already exist:
docs/specs/product-under-test.md
docs/specs/ui-journeys.md
docs/specs/api-endpoints.md
playwright-scaffolding.md
If they do not exist, stop and complete Chapter 1 first.
The main rule of this chapter
playwright-scaffolding.mdis now the application-specific source of truth.
Not the generic harness template.
Not memory.
Not assumptions.
The remaining quick-start process should treat the artifacts from Chapter 1 as durable repo memory.
What this chapter prepares Claude Code to do
After this chapter, Claude Code should be ready to scaffold:
- root repo files
- Playwright config
- docs structure
- plans and templates
CLAUDE.mdAGENTS.md- agent role docs
- page-object folders
- API-client folders
- fixture folders
- sample UI/API/hybrid tests
- reusable utilities
- reports/artifact folders
- validation scripts
- CI workflow skeletons
But before it does any of that, you should package the instructions cleanly.
Step 1 — Review the four required artifacts together
Open these side by side:
docs/specs/product-under-test.md
docs/specs/ui-journeys.md
docs/specs/api-endpoints.md
playwright-scaffolding.md
Ask these questions:
- Do the feature areas in
product-under-test.mdmatch the page and client domains inplaywright-scaffolding.md? - Do the journeys in
ui-journeys.mdmap cleanly to likely test folders and flow helpers? - Do the API domains in
api-endpoints.mdmap cleanly to likely API client classes? - Is auth handled consistently across all four files?
- Is the terminology consistent?
Fix mismatches now. Do not expect Claude Code to resolve ambiguous language perfectly.
Step 2 — Normalize naming before scaffolding
The scaffolding phase gets much better when naming is normalized first.
Normalize these categories
Page names
Choose one canonical name per page or screen.
Examples:
CheckoutPageOrderHistoryPageAccountSettingsPage
Avoid drift like:
- “Account Page”
- “Settings”
- “Profile screen”
- “User settings page”
if they really mean the same thing.
API client domains
Choose one canonical name per endpoint family.
Examples:
AuthClientOrdersClientCatalogClientUsersClient
Flow names
Choose names that represent business behavior.
Examples:
checkout.flow.tslogin.flow.tsaccount-recovery.flow.ts
Component object names
Use these only where repeated UI fragments justify them.
Examples:
Header.tsSidebar.tsToast.tsCartDrawer.ts
Why this matters
If names are unstable during scaffolding, the repo will start with drift and future agents will amplify it.
Step 3 — Decide the initial harness boundaries
A good initial repo is not the whole universe. It is a clear starting slice.
Decide what the initial scaffold must include
Usually:
- smoke UI coverage for 1–3 critical journeys
- smoke API coverage for auth and one major domain
- one hybrid test showing API-assisted UI setup
- basic auth strategy
- basic fixtures
- page objects only for the earliest journeys
- component objects only where immediately useful
- reusable API clients for the earliest endpoint groups
Decide what is out of scope for the first scaffold
Usually:
- full regression suite
- complete page-object coverage of the entire app
- every API endpoint
- every role
- visual regression
- contract-testing sophistication beyond simple schema checks
- performance testing
- mobile emulation unless essential
Write these boundaries into your scaffolding expectations.
Step 4 — Decide the initial directory naming
Before Claude Code scaffolds, be explicit about the major top-level areas.
A strong default is:
src/
core/
ui/
pages/
components/
flows/
assertions/
api/
clients/
builders/
helpers/
schemas/
assertions/
shared/
data/
factories/
utils/
state/
fixtures/
tests/
ui/
smoke/
regression/
accessibility/
api/
smoke/
regression/
contract/
hybrid/
setup/
docs/
architecture/
standards/
runbooks/
specs/
plans/
agents/
decisions/
scripts/
artifacts/
.github/workflows/
This structure is opinionated but practical. It keeps reusable code in src/, specs in tests/, and durable repo memory in docs/.
Step 5 — Decide the opinionated defaults
Before scaffolding, make these rules explicit.
Preferred stack
- Node.js
- TypeScript
- Playwright Test
- npm
- ESLint
- Prettier
- dotenv
- zod
Preferred API harness style
Use Playwright APIRequestContext by default for API automation.
Preferred pattern:
- request context per appropriate scope
- domain-specific wrapper clients
- shared auth setup
- schema validation with
zod - explicit assertions for status, headers, and important body fields
Preferred UI harness style
- selectors live inside the owning page object
- page objects hold reusable page-specific actions
- flows handle multi-page business behavior
- assertion helpers hold reusable domain expectations
- component objects exist only for reused page fragments
Preferred agent loop
At minimum:
Planner → Generator → Evaluator
Secondary roles can be added later:
- Reviewer
- Doc-gardener
Preferred repo-memory style
- short root instruction files
- deep guidance in
docs/ - plans written to files
- handoffs written to files
- evaluator reports written to files
- future agents should be able to continue from repo state alone
These defaults should be visible in the final template.
Step 6 — Prepare the root instruction strategy
Claude Code reads CLAUDE.md at the start of every session. It is the most important file for shaping Claude's behavior, but it must stay under 200 lines. Longer files get ignored.
The solution is to keep CLAUDE.md short and navigational, and use two complementary mechanisms:
@importsyntax —CLAUDE.mdcan reference other files with@path/to/file.md. Claude expands them automatically at session start..claude/rules/— path-scoped rules that only load when Claude is working with matching files.
What CLAUDE.md should contain
# Playwright Automation Harness — [Product Name]
## What this repo is
One-sentence description.
## Source of truth
@playwright-scaffolding.md overrides generic assumptions.
## Key docs
- Product spec: @docs/specs/product-under-test.md
- UI journeys: @docs/specs/ui-journeys.md
- API endpoints: @docs/specs/api-endpoints.md
- Architecture: @docs/architecture/repo-map.md
## Validation
Run before committing:
- `npm run validate` (format, lint, typecheck, smoke)
- `npm run test:smoke`
## Standards
- @docs/standards/coding-standards.md
- @docs/standards/test-writing-standards.md
- @docs/standards/selector-strategy.md
## Work log — IMPORTANT
ALWAYS update CHANGELOG.md before committing. Every entry must include:
- date
- what was done (one-line summary)
- which files were created or changed
- why the change was made
## Agent workflow
Planner → Generator → Evaluator. See @AGENTS.md.
## Plans
- Active plans: docs/plans/active/
- Completed plans: docs/plans/completed/
The @ syntax makes the referenced files available to Claude without repeating their contents in CLAUDE.md. This keeps the root file navigational while giving Claude deep context on demand.
Use .claude/rules/ for path-scoped rules
Instead of putting every coding rule in CLAUDE.md, create rule files in .claude/rules/ that only apply when Claude is working with matching files:
.claude/
└── rules/
├── page-objects.md # rules for src/ui/pages/**
├── api-clients.md # rules for src/api/**
├── test-writing.md # rules for tests/**
└── selectors.md # rules for src/ui/**
Each rule file uses YAML frontmatter to specify which paths it applies to:
---
paths:
- "src/ui/pages/**/*.ts"
---
# Page Object Rules
- Selectors live inside the owning page object, never in test files
- Page objects expose actions, not raw locators
- Use `getByRole`, `getByText`, or `getByTestId` — avoid CSS selectors
- Every page object must have a `waitForReady()` method
---
paths:
- "tests/**/*.ts"
---
# Test Writing Rules
- One assertion concept per test
- Use descriptive test names that read as sentences
- Never use `page.waitForTimeout()` — rely on auto-waiting
- Smoke tests must complete in under 10 seconds
Path-scoped rules are powerful because they:
- do not consume context tokens until Claude actually works with matching files
- prevent rule conflicts (UI rules cannot confuse API work)
- scale as the repo grows without bloating
CLAUDE.md
AGENTS.md — the multi-agent operating model
CLAUDE.md imports AGENTS.md via @AGENTS.md. This file defines role responsibilities and handoff rules:
- role responsibilities
- handoff rules
- when the planner must be consulted
- when the evaluator must fail work
- when docs must be updated
Use .claude/agents/ for native subagents
Claude Code supports native subagents — specialized assistants that run in their own context window with their own set of allowed tools. Instead of only documenting agent roles in docs/agents/, create actual subagent definitions in .claude/agents/:
<!-- .claude/agents/evaluator.md -->
---
name: evaluator
description: Verifies implementation against sprint contract. Use after completing a sprint.
tools: Read, Grep, Glob, Bash
---
You are the evaluator. Your job is to verify implementation quality.
1. Read the sprint contract from docs/plans/active/
2. Run all validation commands listed in the contract
3. Check that acceptance criteria are met
4. Write a PASS/FAIL report to docs/plans/handoffs/
5. If FAIL, list specific issues with file paths and line numbers
<!-- .claude/agents/planner.md -->
---
name: planner
description: Creates sprint contracts and execution plans before implementation work begins.
tools: Read, Grep, Glob
---
You are the planner. Your job is to define scope before coding.
1. Read the request or spec
2. Explore the codebase to understand current state
3. Write a sprint contract to docs/plans/active/
4. The contract must include: scope, out of scope, acceptance criteria, validation commands, expected files to change, risks
Native subagents are better than plain documentation because:
- Claude Code delegates tasks to them automatically based on the
descriptionfield - they run in a separate context window, so investigation work does not clutter your main session
- you can scope their tools (e.g., the evaluator can run Bash commands, but a reviewer might only need Read)
- you can request a specific one:
"use the evaluator subagent to verify my last change"
Keep the role docs in docs/agents/ as human-readable references, but create the .claude/agents/ definitions as the actual working subagents.
Use .claude/skills/ for repeatable workflows
Skills are reusable prompts that Claude applies automatically when relevant, or that you can invoke directly with /skill-name:
<!-- .claude/skills/new-page-object/SKILL.md -->
---
name: new-page-object
description: Create a new page object for a given page
---
Create a new page object for: $ARGUMENTS
1. Read docs/specs/product-under-test.md for context
2. Read docs/standards/selector-strategy.md for selector rules
3. Look at existing page objects in src/ui/pages/ for patterns
4. Create the page object file in src/ui/pages/
5. Add a `waitForReady()` method
6. Export it from the pages index
7. Run `npm run typecheck` to verify
<!-- .claude/skills/new-test-spec/SKILL.md -->
---
name: new-test-spec
description: Create a new test specification file
---
Create a test spec for: $ARGUMENTS
1. Read docs/specs/ui-journeys.md for journey context
2. Look at existing tests in the matching test folder for patterns
3. Create the test file following docs/standards/test-writing-standards.md
4. Run the new test with `npx playwright test <file> --reporter=line`
5. Fix any failures
<!-- .claude/skills/log/SKILL.md -->
---
name: log
description: Update CHANGELOG.md with a summary of recent work
---
Update CHANGELOG.md with what was done in this session.
1. Check git diff and git status for all changes since the last changelog entry
2. Summarize what was accomplished, grouped by feature or concern
3. List all files created or modified with a brief note for each
4. Add the entry at the top of CHANGELOG.md under today's date
5. Stage CHANGELOG.md
Invoke skills directly: /new-page-object CheckoutPage, /new-test-spec checkout smoke, or /log after completing work.
Skills differ from .claude/rules/ in an important way:
- Rules load automatically when Claude touches matching files — use them for standards and constraints
- Skills load on demand when invoked or when Claude determines they are relevant — use them for workflows and procedures
Step 7 — Prepare the planning system
The first scaffold should not only create code folders. It should create an operating system for future work.
That means Claude Code should create at least:
docs/plans/active/
docs/plans/completed/
docs/plans/handoffs/
docs/plans/templates/
Required templates
The scaffold should include templates for:
- sprint contract
- execution plan
- evaluator report
What each should contain
Sprint contract
- task name
- linked request or spec
- scope
- out of scope
- acceptance criteria
- validation commands
- expected files to change
- risks and assumptions
Execution plan
- problem statement
- approach
- phases
- progress log
- decisions
- follow-up debt
Evaluator report
- contract reviewed
- commands run
- environment
- pass/fail summary
- evidence
- missing coverage
- recommendation
This makes future long-running agent work much more reliable.
Step 8 — Decide the initial validation gate
The initial repo should be easy to validate frequently.
That means the scaffold should support scripts like:
npm run bootstrap
npm run lint
npm run format
npm run format:check
npm run typecheck
npm run test
npm run test:ui
npm run test:api
npm run test:smoke
npm run test:contract
npm run test:a11y
npm run docs:check
npm run validate
npm run report
npm run plan:init
npm run new:spec
Recommended meaning of validate
Keep it concise but useful.
A good default is:
- format check
- lint
- typecheck
- smoke tests
Do not make the local validation gate so heavy that agents stop using it.
Step 9 — Decide the artifact and debugging conventions
The scaffold should create predictable local outputs.
Use:
artifacts/
reports/
screenshots/
videos/
traces/
logs/
And the future runbooks should explain:
- how to run one test
- how to open the HTML report
- how to inspect traces
- how to regenerate auth state
- how to run only API tests
- how to switch environment
Redaction rule
The scaffold should encode:
- never log raw secrets
- never log full tokens
- redact auth headers
- redact cookies
- redact PII
- redact session values in logs and artifacts where practical
Step 10 — Decide the initial CI expectations
The first scaffold should be CI-aware even if CI is still minimal.
A good default is to prepare:
.github/workflows/ci.yml
.github/workflows/smoke.yml
.github/workflows/docs-check.yml
Expectations
ci.yml
- install dependencies
- lint
- typecheck
- run smoke UI and API tests
- upload Playwright report and failure artifacts when needed
smoke.yml
- manual or scheduled smoke run
docs-check.yml
- verify required docs exist
- verify key links or file presence where practical
These do not need to be perfect from day one, but the structure should be in place.
Step 11 — Choose the right permission mode for scaffolding
Claude Code has several permission modes that control how often it pauses to ask for approval. The default mode asks before every file edit and every shell command. During scaffolding, that means approving dozens of file creations one by one — tedious and unnecessary.
Recommended: acceptEdits mode
For the scaffolding step, start Claude Code in acceptEdits mode:
claude --permission-mode acceptEdits -n scaffolding
In this mode, Claude creates and edits files without prompting. Shell commands (like npm install) still require approval. This is the right balance: you let Claude build the file structure uninterrupted, but stay in control of anything that installs packages or modifies system state.
Alternative: auto mode
If your account supports it (Team, Enterprise, or API plan), auto mode eliminates nearly all prompts. A separate classifier model reviews each action and blocks anything that looks risky:
claude --permission-mode auto -n scaffolding
Auto mode is ideal for long scaffolding runs where you want to step away and let Claude work.
Alternative: worktree isolation
For extra safety, scaffold in a Git worktree. Claude works in an isolated copy of the repo, and you review the result before merging:
claude --worktree scaffolding
This creates .claude/worktrees/scaffolding/ with its own branch. If you do not like the result, the worktree is discarded cleanly.
If the scaffold needs .env files from your main repo, create a .worktreeinclude file in the project root:
.env
.env.local
What not to use
Do not use --dangerously-skip-permissions (bypass mode) unless you are inside an isolated container or VM. It disables all safety checks.
Step 12 — Prepare hooks for automated quality checks
Claude Code supports hooks — shell commands that run automatically at specific points in Claude's workflow. Unlike CLAUDE.md instructions (which are advisory), hooks are deterministic. If a hook fails, Claude's action is blocked.
Recommended hooks for the scaffold
Add these to .claude/settings.json (or ask Claude to write them: "Write a hook that runs eslint after every file edit"):
Lint after every file edit
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "npx eslint --fix $CLAUDE_FILE_PATH 2>/dev/null || true"
}
]
}
]
}
}
Notify when Claude needs attention
If you step away during scaffolding, get a desktop notification:
{
"hooks": {
"Notification": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "osascript -e 'display notification \"Claude Code needs your attention\" with title \"Claude Code\"'"
}
]
}
]
}
}
Block commits without a changelog entry
Claude can update CHANGELOG.md when asked, but it does not do it consistently. A CLAUDE.md instruction helps (~70–80% of the time), but the only guaranteed enforcement is a hook that blocks the commit if CHANGELOG.md is not staged:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash(git commit*)",
"hooks": [
{
"type": "command",
"command": "git diff --cached --name-only | grep -q 'CHANGELOG.md' || (echo 'BLOCKED: Update CHANGELOG.md before committing. Summarize what was done, why, and which files changed.' && exit 1)"
}
]
}
]
}
}
When Claude tries to commit without updating the changelog, the hook fails with a clear message. Claude sees the error, goes back, updates CHANGELOG.md, stages it, and retries the commit. This works in every permission mode, including auto.
Pair this hook with the /log skill from Step 6 and the CLAUDE.md rule below for a three-layer approach:
| Layer | Mechanism | Reliability |
|---|---|---|
| Hook (PreToolUse on commit) | Blocks the commit — Claude cannot skip it | 100% |
| CLAUDE.md rule | Reminds Claude to update the log throughout the session | ~70–80% |
/log skill |
Manual trigger when you want an entry without committing | 100% (you invoke it) |
Why hooks matter for autonomous work
When Claude runs in acceptEdits or auto mode, it makes many changes without pausing. Hooks ensure that standards are enforced on every edit, even when you are not watching. This is especially important during scaffolding, where dozens of files are created in sequence.
Step 13 — Prepare the exact prompt package for Claude Code
Before moving to Chapter 3, prepare the final set of inputs Claude Code will read.
These are:
playwright-scaffolding.md
docs/specs/product-under-test.md
docs/specs/ui-journeys.md
docs/specs/api-endpoints.md
Optionally, you may also include:
docs/discovery/site-map-notes.md
docs/discovery/navigation-notes.md
docs/discovery/api-notes.md
docs/discovery/auth-notes.md
docs/discovery/open-questions.md
These optional files are useful when the app has complexity or ambiguity.
Step 14 — Final pre-scaffolding checklist
Do not move to Chapter 3 until all of the following are true:
- the application’s real structure is captured
- names are normalized
- auth/session behavior is explicit
- journey priorities are explicit
- API client domains are explicit
- initial scope is bounded
- opinionated defaults are explicit
- the required input files exist
- permission mode decision is made (
acceptEditsorauto) - hook strategy is decided (at minimum: lint-on-edit, changelog-on-commit, notifications)
- work log strategy is decided (CLAUDE.md rule + commit hook +
/logskill) .claude/rules/path-scoped rules are planned.claude/agents/subagent definitions are planned- you are ready for Claude Code to scaffold from those files
What not to do in this chapter
Do not:
- write the actual scaffold prompt yet
- start implementation yet
- create placeholder-heavy files with no real product content
- let generic names survive when real names are known
- add every possible future framework to the planned scaffold
This chapter is about making the handoff to scaffolding clean and deterministic.
Deliverable from Chapter 2
You should now have:
- the four required source artifacts from Chapter 1
- a clear set of opinionated harness defaults
- a
CLAUDE.mdstrategy that uses@importsand stays under 200 lines .claude/rules/path-scoped rules planned for UI, API, and test code.claude/agents/native subagent definitions planned (planner, generator, evaluator).claude/skills/repeatable workflow definitions planned- a hook strategy for automated quality checks and work log enforcement
- a work log strategy (CLAUDE.md rule + commit hook +
/logskill) - a permission mode decision (
acceptEditsorauto) for uninterrupted scaffolding - a clear plan/template strategy
- a clear validation and CI expectation
- a clear understanding of what the initial scaffold must include
Now Claude Code can scaffold an initial repo state without guessing too much.