AI-powered AWS architecture designer β Step Functions + Strands agent core
Describe your application in natural language and Scaffold AI designs the AWS serverless architecture, runs a security review against AWS Well-Architected principles, and generates deployment-ready infrastructure-as-code -- all through a visual canvas and chat interface.
See the interactive Architecture Overview for a visual summary of agents, functions, infrastructure, and data flow.
After building Resume Tailor AI with AWS Step Functions, I wanted to explore modern AI orchestration. I originally built this with LangGraph, then refactored to Step Functions + Strands to align the entire portfolio on a consistent, AWS-native agent pattern.
The goal was to demonstrate:
- Learning velocity -- Shipping production-quality code in unfamiliar frameworks, fast
- Architectural judgment -- Knowing when to refactor and why, not just when to build
- Production mindset -- Security gates, rate limiting, input validation, and testing from the start, not bolted on later
| Resume Tailor AI | Project Planner AI | Scaffold AI | Career Path Architect | |
|---|---|---|---|---|
| Purpose | Resume optimization | Project planning | AWS architecture design | Career planning |
| Orchestration | AWS Step Functions | AWS Step Functions | AWS Step Functions | LangGraph |
| Agents | Step Functions workflow | SFN Map + Strands | 5 SFN Lambda + Strands | 6 LangGraph agents |
| Tests | 212 tests, 98% | 109 tests, 92% | 418 tests, 95% | 142 tests, 99% |
| Features | Resume tailoring | Architecture planning | Architecture generation | Roadmap + Critical Review |
All projects share the same production patterns (validation, error handling, pre-commit hooks, CI/CD, rate limiting, testing).
| Blank canvas | Architecture generated from prompt |
|---|---|
![]() |
![]() |
| Security review (failed -- score 62/100) | Architecture updated with security fixes |
|---|---|
![]() |
![]() |
| Generated CDK code | Export and deploy options |
|---|---|
![]() |
![]() |
User Input --> Interpreter --> Architect --> Security Specialist --> Code Generator
| | | |
Intent class Graph nodes Security score CDK / Terraform / CF
- Interpreter Agent -- Classifies user intent (new feature, modify, explain, deploy)
- Architect Agent -- Designs AWS serverless architecture with 65+ AWS service node types
- Security Specialist -- Validates against AWS Well-Architected principles; blocks insecure designs (score < 70/100)
- Code Generators -- Multi-format IaC output (CDK TypeScript, CDK Python, CloudFormation, Terraform)
- React Specialist -- Generates AWS Cloudscape UI components
- Visual Canvas -- React Flow node graph editor with drag-and-drop AWS service nodes
- AI Chat -- Natural language architecture design powered by AWS Bedrock (Claude)
- Security Gate -- Automated scoring blocks code generation for insecure architectures
- Security Badges -- Visual indicators on each node showing active security configs (encryption, WAF, auth)
- Security Auto-Fix -- One-click security remediation with fail banner (Auto-Fix / Mark Resolved)
- Multi-Format IaC -- Generate CDK TypeScript, CDK Python, CloudFormation, or Terraform
- Code Viewer -- Tabbed modal for browsing generated infrastructure code
- Export & Deploy -- Download as ZIP or deploy directly to AWS with CDK
- Project Planner Integration -- Structured API integration with session-based storage
- Shared Types Package -- Type-safe data transfer with Project Planner AI
- Rate Limiting -- 10 req/min chat, 3 req/hr deployment, 20 req/min plan import
- Dark/Light Mode -- Toggle with localStorage persistence, CSS custom properties (
--sa-*), Cloudscape Mode switching - Chat Session Sidebar -- Session list with rename, delete, resume; auto-creates sessions on first message
- Markdown Chat --
react-markdown+remark-gfmfor rich assistant messages (tables, code blocks, lists) - Toast Notifications -- Flashbar-based auto-dismiss toasts via AuthContext
- Keyboard Shortcuts -- Ctrl+K focus chat input, Escape close modals
- Empty States -- Friendly empty states for chat and session sidebar
- Responsive Layout -- Media queries stack columns on mobile, hide chat sidebar on small screens
- Pre-commit Hooks -- TruffleHog secrets detection, AWS credentials scanning
Scaffold AI receives project plans from Project Planner AI via structured API:
- DynamoDB handoff - Planner writes plan data to
project-planner-handofftable, Scaffold reads via URL params - Session-based storage - Plans stored with unique session IDs and 24h TTL
- Cognito-authenticated - Both Planner (write) and Scaffold (read) use IAM-authenticated DynamoDB access
- Graceful fallback - Falls back to clipboard-based import if DynamoDB is unavailable
- Auto-populated chat - Project context pre-filled from plan data
- 7 comprehensive tests - Full test coverage for import functionality
The integration enables a seamless workflow: Plan β Build β Deploy.
| Layer | Technology |
|---|---|
| AI Orchestration | AWS Step Functions + Strands |
| LLM | AWS Bedrock (Claude) |
| Backend | AWS Lambda (Python 3.13+) + Step Functions |
| Frontend | React 19 + Vite SPA |
| UI Library | AWS Cloudscape Design System |
| State | Zustand |
| Canvas | React Flow |
| Testing | pytest + Vitest |
| Tooling | pnpm + Turborepo + uv |
| Tier | Model | Use Case |
|---|---|---|
testing (default) |
Claude Haiku 4.5 | Fast, cost-effective β local dev and CI |
optimized |
Claude Sonnet 4.5 | Balanced quality and cost |
premium |
Claude Opus 4.5 | Highest quality for production |
Set DEPLOYMENT_TIER in your .env to switch tiers. Override any tier with BEDROCK_MODEL_ID.
- Python 3.13+
- Node.js 22+
- pnpm 10+
- AWS CLI configured with Bedrock access
- uv (Python package manager)
# Clone repository
git clone https://github.com/jfowler-cloud/scaffold-ai.git
cd scaffold-ai
# Install frontend dependencies
pnpm install
# Backend setup
cd apps/backend
uv sync
cp .env.example .env
# Edit .env with your AWS credentials# Frontend (port 3000)
cd apps/web
pnpm devNote: The
apps/backend/FastAPI server is for local development only. In production, Scaffold AI uses AWS Lambda functions invoked via Step Functions. The frontend calls AWS services directly via Cognito identity pool credentials.
Backend (apps/backend/.env):
AWS_REGION=us-east-1
# Prefer AWS_PROFILE or IAM role-based auth (recommended)
AWS_PROFILE=your_profile
# Raw keys work but are not recommended β use profile or IAM role instead
# AWS_ACCESS_KEY_ID=your_access_key
# AWS_SECRET_ACCESS_KEY=your_secret_key
BACKEND_URL=http://localhost:8001
PORT=8001
# Deployment tier (testing/optimized/premium) β default: testing
DEPLOYMENT_TIER=testing
# Model override β leave blank to use tier default
BEDROCK_MODEL_ID=Frontend (apps/web/.env):
VITE_BACKEND_URL=http://localhost:8001scaffold-ai/
βββ apps/
β βββ backend/ # FastAPI β fire-and-poll API
β β βββ src/scaffold_ai/
β β β βββ main.py # FastAPI app (/api/chat starts SFN, /api/chat/{arn}/status polls)
β β β βββ agents/ # Specialist agents (CDK, React, security, etc.)
β β β βββ services/ # Business services (cost estimator, security autofix, etc.)
β β β βββ tools/ # Git, CDK synthesis
β β βββ tests/
β β
β βββ functions/ # Lambda handlers β one per Step Functions state
β β βββ interpret/ # Classify user intent
β β βββ architect/ # Design/modify architecture graph
β β βββ security_review/ # Security gate (blocks code gen if failed)
β β βββ cdk_specialist/ # Generate IaC (CDK/CF/TF/Python-CDK)
β β βββ react_specialist/ # Generate React component scaffolding
β β βββ get_execution/ # Poll SFN execution status
β β
β βββ agents/
β β βββ shared/ # config.py, db.py β shared across functions
β β
β βββ infra/ # CDK infrastructure
β β βββ lib/workflow-stack.ts # Step Functions + alarms + budget
β β βββ test/ # Snapshot + assertion tests (15 tests)
β β
β βββ web/ # React 19 + Vite SPA
β βββ src/ # App entry point and root component
β βββ src/test/ # e2e-main.tsx, e2e-auth-stub.ts
β βββ e2e/ # Playwright E2E + accessibility specs
β βββ components/ # Cloudscape components, Canvas, Chat
β βββ lib/ # Zustand stores
β
βββ packages/
β βββ generated/ # IaC output
β βββ ui/ # Shared components
β
βββ docs/
βββ steering/ # Cloudscape UI patterns
# Backend tests
cd apps/backend
uv run pytest -v
# Frontend tests
cd apps/web
pnpm test
# All tests (from root)
pnpm test:allTests cover agents, services, Lambda handlers, API endpoints, input validation, rate limiting, and frontend components/stores.
| Resume Tailor AI | Scaffold AI | Career Path Architect | |
|---|---|---|---|
| Orchestration | AWS Step Functions | AWS Step Functions | LangGraph |
| Use case | Deterministic resume tailoring | Dynamic AI multi-agent conversations | Career planning & roadmaps |
| State management | S3 + DynamoDB | Step Functions + DynamoDB | LangGraph built-in memory |
| Deployment | AWS-native (Lambda, Step Functions) | AWS-native (Lambda, Step Functions) | Framework-agnostic |
All three projects share production patterns: input validation, error handling, pre-commit hooks, CI/CD with security scanning, rate limiting, and comprehensive testing.
- Development Journey -- Build timeline and key decisions
- Multi-Format IaC -- IaC generation patterns
- Contributing -- Development setup and guidelines
- Testing Summary -- Test coverage and strategy
- Security Audit -- Security review and improvements
- Critical Review -- Self-assessment and roadmap
Honest assessment of the codebase as of Feb 2026, based on a full source review. See also CRITICAL_REVIEW.md for the detailed 44-item audit.
usePlannerImport.ts now supports two import modes: (1) session-based API (/api/import/plan/{sessionId}) which returns fully structured data, and (2) legacy ?prompt= fallback with parsePrompt() that extracts project name, architecture, tech stack, and requirements from the formatted prompt text. Chat auto-submit now builds a rich prompt including all structured fields, review findings, and review summary.
All endpoints are public. All state (architectures, chat history, sharing links, security scores) is stored in memory and lost on restart. The deploy endpoint runs cdk deploy with full system access and no user validation.
Recommendation (short-term): Add API key validation middleware for the deploy endpoint. Add a projects dict keyed by session ID so architectures survive page refreshes. Recommendation (medium-term): Add Cognito auth + DynamoDB persistence as outlined in CRITICAL_REVIEW.md Phase 1.
cdk_deployment.py executes npm install and npx cdk deploy via subprocess.run with no container isolation, no disk space checks, and no cleanup on failure. A malicious or buggy CDK template could write anywhere on the filesystem.
Recommendation: Run CDK synthesis and deployment inside a Docker container with a read-only root filesystem and a tmpfs work directory. Add explicit timeouts and cleanup logic in finally blocks.
15+ except Exception as e blocks across the codebase catch everything and return generic "An internal error occurred" messages. This makes debugging difficult and hides transient vs. permanent failures.
Recommendation: Create a custom exception hierarchy (ScaffoldError, LLMError, DeploymentError, etc.). Catch specific exceptions, log with request context, and return structured error responses with error codes.
Correction: user_input: str has no max length constraint.ChatRequest does validate user_input with a 5000-char limit and non-empty check via field_validator. However, graph_json: dict | None is still unvalidated -- there is no schema check, no node count limit, and no max depth. A crafted graph payload could cause the architect prompt to exceed the LLM context window or produce excessive token costs.
Recommendation: Add a Pydantic validator for graph_json that rejects graphs with more than 50 nodes. Validate that node IDs and types match expected formats.
All frontend files now import BACKEND_URL / PLANNER_URL from lib/config.ts. The stale NEXT_PUBLIC_* env var references have been removed.
Removed unused InterpreterAgent and ArchitectAgent classes. The files now contain only their system prompt constants, which are referenced by the Lambda handlers in apps/functions/. The __init__.py comment has been updated accordingly.
The /api/deploy endpoint accepts raw cdk_code and app_code strings from the client and writes them to disk before executing cdk deploy. While stack_name is validated against a regex to prevent command injection, the code content itself is not inspected. An attacker could submit CDK code containing child_process.exec() or filesystem operations. The deployment runs with the server's full AWS credentials.
Recommendation: At minimum, validate that the CDK code only imports from aws-cdk-lib and constructs. Better: run synthesis in a Docker container with restricted network access and no AWS credentials, then deploy the synthesized CloudFormation template directly.
PlannerNotification.tsx now conditionally renders architecture and tech stack using Β· separators, and shows review findings count with critical/high breakdown. No more dangling punctuation from empty fields.
All backend calls in Chat.tsx now use BACKEND_URL from lib/config.ts. The chat flow uses a shared sendChatRequest() helper with fire-and-poll (matching the Step Functions backend), and all other calls (security autofix, deploy) also use BACKEND_URL consistently.
_write_generated_file in nodes.py walks up 8 parent directories looking for package.json to find the repo root. If the backend is run from an unexpected working directory or the file structure changes, generated files may be written to the wrong location or silently fail.
Recommendation: Resolve the repo root once at startup via an environment variable or by walking from __file__ with a known anchor (e.g., apps/backend). Cache the result instead of re-walking on every write.
The planner-to-scaffold handoff works end-to-end via DynamoDB:
- DynamoDB handoff (primary): Planner writes plan data to
project-planner-handoffDynamoDB table via Cognito credentials, opens Scaffold AI with?from=planner&session=.... Scaffold reads full structured data including review findings. - Clipboard fallback: If DynamoDB write fails, plan description is copied to clipboard for manual paste.
Chat auto-submit builds a rich prompt with project name, architecture, tech stack, requirements, and review findings. The notification banner displays all available context.
Contributions welcome! See CONTRIBUTING.md for guidelines.
- Fork the repository
- Create a feature branch:
git checkout -b feature/amazing-feature - Make changes and add tests
- Run tests:
pnpm test:all - Commit:
git commit -m 'feat: add amazing feature' - Push and open a Pull Request
- Frontend Chat now uses fire-and-poll pattern matching the Step Functions backend (
sendChatRequest+pollExecution) - Planner auto-submit builds rich prompt with structured fields (project name, architecture, tech stack, requirements, review findings)
PlannerNotificationdisplays tech stack, review findings count with critical/high breakdown, no dangling punctuation- Removed unused
InterpreterAgentandArchitectAgentclasses (kept system prompt constants for Lambda handlers) - Updated
__init__.pyandCLAUDE.mdto reflect Step Functions architecture - 5 new tests (structured planner data, review findings, workflow failure, non-ok start, fire-and-poll cycle)
- 418 tests passing across all suites (121 backend, 12 functions, 10 agents, 262 frontend, 15 CDK)
Looking for the LangGraph version? The previous LangGraph-based orchestration is preserved on the
legacy/langgraphbranch.
- π Replaced LangGraph with AWS Step Functions + Strands agent core
- π Each workflow node is now an independent Lambda handler in
apps/functions/ - π
/api/chatis now fire-and-poll β returnsexecution_arnimmediately, poll/api/chat/{arn}/status - β¨ Added
apps/infra/CDK stack defining the Step Functions state machine - β¨ Added
apps/agents/shared/config + db helpers (consistent with PSP/idea-fairy pattern) - β¨ CloudWatch alarms (Lambda error rate, P99 duration, SFN execution failures)
- β¨ AWS Budget alarm ($25/mo, 80% threshold) with SNS topic
- β¨ CDK cost tags (
Project,Environment,ManagedBy) on all resources - β¨ CDK snapshot + assertion tests (15 tests)
- β¨ Accessibility tests (
@axe-core/playwright) with WCAG 2.0 AA checks - β¨ E2E test stubs (
e2e-main.tsx,e2e-auth-stub.ts) - π Coverage improved: 64% β 95% (frontend: 262 tests, thresholds ratcheted to 96/88/94/97)
- Removed duplicate
SecurityAutoFixclass stub fromsecurity_autofix.py - Added
graph_jsonnode count validation toChatRequest(max 50 nodes, consistent withGraphRequest) - Fixed fragile repo root resolution in
_write_generated_fileβ now usesPath(__file__).parents[4]with anchor validation instead of walking up 8 levels looking forpackage.json - Cleaned up
agents/__init__.pyβ removed unusedInterpreterAgent/ArchitectAgentexports, added clarifying comment - README: added Project Planner AI to comparison table, removed raw AWS key example, added
PORTenv var, removed rocket emoji from header
- β¨ Added SecurityBadge component to all 11 node types β shows active security configs (encryption, WAF, auth, etc.)
- β¨ Security fix visualization β auto-fix normalizes node types for React Flow rendering
- β¨ Security review fail banner with Auto-Fix and Mark Resolved actions
- β¨ Deploy to AWS modal with "coming soon" notice and manual deployment instructions
- β¨ Centralized BACKEND_URL config (
lib/config.ts) β single source of truth for backend URL - β¨ Added
skip_securityflag to workflow state for bypassing security gate - π Fixed all 11 node files β removed duplicate JSX bodies
- π Fixed security gate test assertions and added missing GraphState fields
- β 126 tests passing (up from 116)
- Fixed React hydration mismatch on Cloudscape
SplitPanelβaria-valuenowon the resize handle is computed fromwindow.width(client-only), causing SSR/client tree mismatch; deferredsplitPanelprop render until after mount - Fixed all Bedrock model IDs to use
us.cross-region inference profile prefix (e.g.us.anthropic.claude-haiku-4-5-20251001-v1:0) β bare IDs were rejected by Bedrock in theus-east-1region - Updated coverage badge to 64% (measured with pytest-cov; added
pytest-covto dev dependencies) - Removed
mountedguard that was blocking full-page render for 4+ seconds on planner handoff - Scoped global CSS transition to
.theme-transitioningclass only (was applying to every element on every paint) - Fixed CORS default to include
localhost:3001alongsidelocalhost:3000 - Auto-submit planner import to chat immediately instead of just populating textarea
- Fixed
test_security_gate_blocks_insecure_architectureandtest_security_gate_passes_secure_architectureβ both were making real Bedrock calls in CI (no credentials); now properly mockget_llmwith ordered side effects - Fixed
optimizedtier model ID:anthropic.claude-sonnet-4-5-20250929-v1:0(was20251001) - 121 backend tests passing
- β¨ Added
config.pywithtesting/optimized/premiumdeployment tier system - β¨ Testing tier: Claude Haiku 4.5 (default) β fast and cost-effective
- β¨ Optimized tier: Claude Sonnet 4.5 β balanced quality and cost
- β¨ Premium tier: Claude Opus 4.5 β highest quality
- π§
DEPLOYMENT_TIERenv var controls model selection;BEDROCK_MODEL_IDoverrides - π Added model tier table to README and
.env.example
- β¨ Upgraded to Claude Opus 4.5 with cross-region inference profile
- β¨ Added portfolio context and capability badges to README
- π Fixed hydration mismatch with loading state
- π Resolved jszip module not found error
- π Polished README for public release
- π§ Made type check and security scan non-blocking in CI
- π¦ Dependency Updates:
- @cloudscape-design/components and chat-components to latest
- @eslint/js from 9.39.2 to 10.0.1
- Bumped actions/checkout from 4 to 6, actions/setup-node from 4 to 6, actions/setup-python from 5 to 6
- β¨ Added dark mode toggle with enhanced CSS patterns
- β¨ Added Scaffold AI logo
- β¨ Added Download ZIP button for generated files
- β¨ Styled Select dropdowns for dark mode
- π Fixed canvas toolbar container in dark mode
- π Fixed Deploy button for CloudFormation with manual instructions
- π Used dynamic timestamps in sharing and history services
- π§ Added GitHub Actions CI workflow
- β¨ Added rate limiting, request timeout, and security hardening
- β¨ Added security history tracking
- β¨ Added architecture sharing and collaboration
- β¨ Added multi-stack architecture support
- β¨ Added Python CDK support
- β¨ Added architecture templates library
- β¨ Added security auto-fix capabilities
- β¨ Added cost estimation feature
- π Critical security fixes and hardening
- π Updated roadmap β 7/9 medium-term items complete
- β¨ Added frontend unit test suite with Vitest
- β¨ Added SecuritySpecialistAgent unit tests (19 tests)
- β¨ Added configurable CORS and CDK CloudFront support
- β¨ Added security gate and multi-format IaC generation
- π Fixed CF/TF node type mismatch
- π Resolved all test failures β mock paths, key names, and missing labels
- π Added comprehensive CLAUDE.md for AI assistant onboarding
- π Serverless-first architecture with 65+ AWS service node types
- π Step Functions + Strands multi-agent workflow with security specialist
- π Interactive drag-and-drop architecture canvas
- π CloudFormation and Terraform IaC generation
- π Real-time AI chat for architecture guidance
Chat markdown rendering: AddDONEreact-markdown+remark-gfmtoChat.tsx
This project has chat markdown rendering with react-markdown + remark-gfm, CSS custom properties (:root dark/light color palette with sa- prefix), notification toasts (Flashbar with auto-dismiss), keyboard shortcuts (Ctrl+K focus chat, Esc close modals), empty state illustrations, responsive media queries, light mode Authenticator/TopNavigation polish, session sidebar styles, and smooth theme transitions. Chat session rename/delete and metric card hover effects from recon-ai may be backported in a future pass.
MIT License -- see LICENSE for details.
- Project Planner AI - AI-powered project planning β generates architecture plans that hand off directly to Scaffold AI
- Resume Tailor AI - AI-powered resume optimization with Claude Opus 4.5 (3 days, 212 tests, 98% coverage)
- Career Path Architect - AI-powered career planning with LangGraph (2 hours, 142 tests, 99% coverage)
Together, these projects form a complete AI-powered career development platform.
James Fowler
- GitHub: @jfowler-cloud
- LinkedIn: James Fowler - AWS Cloud Architect & DevOps Professional






