
Technical Requirements Interview
- 87 installs
- 1 repo stars
- Updated June 17, 2026
- validkeys/sherpy
Helps with ai & agent building tasks.
About
technical-requirements-interview is a Claude Code skill in the AI & Agent Building category.
- technical-requirements-interview
- AI & Agent Building
- AI-coding skill
Technical Requirements Interview by the numbers
- 87 all-time installs (skills.sh)
- +2 installs in the week ending Aug 5, 2026 (Skillselion tracking)
- Ranked #4,982 of 16,546 AI & Agent Building skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/validkeys/sherpy --skill technical-requirements-interviewAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 87 |
|---|---|
| repo stars | ★ 1 |
| Last updated | June 17, 2026 |
| Repository | validkeys/sherpy ↗ |
What it does
Helps with ai & agent building tasks.
Files
Technical Requirements Interview
This skill guides you through a structured interview to derive technical requirements from business requirements.
Prerequisites
- Completed
{base_directory}/requirements/business-requirements.yamlfile - Clear understanding of the problem domain
Interview Process
Rules
1. One question at a time - Never ask multiple questions in a single turn 2. Business context first - Load and understand business requirements before asking technical questions 3. Provide options - Each question includes 2-5 recommended options plus free-form input 4. Track progress - All Q&A pairs are immediately appended to {base_directory}/artifacts/technical-interview.jsonl 5. Resume capability - If JSONL exists, continue from last question 6. Structured output - Generate technical-requirements.yaml in {base_directory}/requirements/ upon completion
Interview Categories
The interview covers these areas in order:
1. Architecture & Patterns
- Overall architecture style
- Application structure
- Component organization
2. Technology Stack
- Programming language
- Frameworks and libraries
- Package management
3. Data Model & Storage
- Data persistence strategy
- Database selection
- Schema design approach
4. API Design
- API style (REST, GraphQL, RPC)
- API framework
- Versioning strategy
5. Security & Authentication
- Authentication method
- Authorization approach
- Secrets management
6. Testing Strategy
- Testing approach (TDD, BDD, etc.)
- Test types (unit, integration, e2e)
- Testing frameworks
7. Development & Tooling
- Development workflow
- Code quality tools
- CI/CD approach
8. Deployment & Distribution
- Deployment target
- Packaging strategy
- Release process
Question Format
Each question follows this structure:
## [Category Name]
**Question:** [Clear, specific question]
**Options:**
1. [Option 1] (Recommended) - [Brief description and rationale]
2. [Option 2] - [Brief description]
3. [Option 3] - [Brief description]
4. Type your own answerExample Questions
Architecture
## Architecture & Patterns
**Question:** What architecture pattern best fits this project?
**Options:**
1. Monolithic application (Recommended) - Single deployable unit, simpler to develop and deploy initially
2. Microservices - Multiple independent services, better scaling but higher complexity
3. Serverless functions - Event-driven, scales automatically, but vendor lock-in
4. Plugin-based - Core engine with extensible plugins for flexibility
5. Type your own answerTechnology Stack
## Technology Stack
**Question:** Which programming language should be used?
**Options:**
1. TypeScript (Recommended) - Type-safe JavaScript, excellent tooling, large ecosystem
2. Python - Readable, extensive libraries, good for data processing and scripting
3. Go - Fast compilation, excellent concurrency, simple deployment
4. Rust - Memory safety without garbage collection, high performance
5. Type your own answerData Storage
## Data Model & Storage
**Question:** What data persistence strategy is appropriate?
**Options:**
1. File-based storage (Recommended) - Simple, portable, no database dependency
2. SQLite - Embedded relational database, good for local tools
3. PostgreSQL - Full-featured relational database, better for complex queries
4. NoSQL (MongoDB, etc.) - Flexible schema, good for document-based data
5. In-memory only - Fast but no persistence, suitable for ephemeral data
6. Type your own answerJSONL Format
Track all questions and answers in {base_directory}/artifacts/technical-interview.jsonl.
See [references/interview-jsonl-spec.md](references/interview-jsonl-spec.md) for the complete JSONL schema with field definitions and examples.
Output Format
Generate {base_directory}/requirements/technical-requirements.yaml upon interview completion.
Create directory if it doesn't exist:
mkdir -p {base_directory}/requirements
mkdir -p {base_directory}/artifactsThe output document includes these top-level sections: project, version, generated, business_requirements_ref, architecture, technology_stack, project_structure, data_model, api, security, testing, development, ci_cd, deployment, monitoring, performance, scalability, constraints, trade_offs, and open_questions.
See [references/output-spec.md](references/output-spec.md) for the complete document specification with all fields, types, and validation rules.
See [references/example.yaml](references/example.yaml) for a full example.
Usage
To start a new technical interview:
/technical-requirements-interview [base-directory]If no directory is provided, auto-detect by looking for requirements/business-requirements.yaml in the current directory.
If not found, prompt the user: "Where are your requirements documents located?"
Wait for the user to provide a path before proceeding. Store as base_directory.
The skill will automatically:
1. Load business requirements from {base_directory}/requirements/business-requirements.yaml as context 2. Check for existing {base_directory}/artifacts/technical-interview.jsonl 3. Resume from last question if found 4. Ask targeted technical questions 5. Generate technical-requirements.yaml in {base_directory}/requirements/ when complete 6. Save interview transcript to {base_directory}/artifacts/technical-interview.jsonl
Decision Tracking
Each technical decision should include:
1. Decision - What was decided 2. Rationale - Why this approach 3. Alternatives considered - What else was evaluated 4. Trade-offs - What was gained/lost 5. Reversibility - How hard to change later
Best Practices
1. Align with business needs - Every technical choice should support business requirements 2. Consider constraints - Respect timeline, budget, and skill constraints 3. Start simple - Choose simpler solutions over complex ones when possible 4. Plan for change - Make reversible decisions where possible 5. Document rationale - Future you will thank present you
Review & Gap Analysis
After generating technical-requirements.yaml, automatically perform a gap analysis:
Alignment Check
Business Alignment:
- [ ] Architecture supports all functional requirements
- [ ] Technology choices align with business constraints
- [ ] Timeline is realistic for technical scope
- [ ] Budget constraints respected in tool/service choices
Completeness Check:
Architecture:
- [ ] Architecture pattern is clearly defined
- [ ] Components and responsibilities documented
- [ ] Data flow is clear
- [ ] Integration points identified
Technology Stack:
- [ ] Language and runtime specified
- [ ] Frameworks and libraries listed
- [ ] Versions specified where critical
- [ ] Alternatives considered and documented
Data Model:
- [ ] Storage strategy defined
- [ ] Schema approach documented
- [ ] Migration strategy if using database
- [ ] Data validation approach specified
API:
- [ ] API style chosen (REST/GraphQL/RPC)
- [ ] Framework selected
- [ ] Versioning strategy defined
- [ ] Documentation approach specified
Security:
- [ ] Authentication method defined
- [ ] Authorization model specified
- [ ] Secrets management approach
- [ ] Input/output validation strategy
Testing:
- [ ] Testing strategy defined (TDD/BDD/etc)
- [ ] Test types specified (unit/integration/e2e)
- [ ] Frameworks selected
- [ ] Coverage targets set
Deployment:
- [ ] Deployment target identified
- [ ] Packaging format chosen
- [ ] CI/CD approach defined
- [ ] Release process documented
Consistency Check
- [ ] No contradictions between technical decisions
- [ ] Technology choices compatible with each other
- [ ] Performance targets achievable with chosen stack
- [ ] Security approach matches data sensitivity
Trade-off Analysis
Review documented trade-offs:
- [ ] Each trade-off has clear rationale
- [ ] Alternatives were seriously considered
- [ ] Consequences understood and acceptable
- [ ] Reversibility assessed
Gap Identification
Common Gaps to Check:
- Missing error handling strategy
- Undocumented edge cases
- Unaddressed scalability concerns
- Missing monitoring/observability plan
- Unclear data migration path
- Missing security threat model
- Undocumented performance budgets
- Missing disaster recovery plan
- Unclear dependency versioning strategy
- Missing code quality tooling
Open Questions Review
Check if open questions are:
- [ ] Clearly stated
- [ ] Have identified options
- [ ] Impact is understood
- [ ] Decision timeline defined
Review Output
Generate a gap analysis report with:
gap_analysis:
business_alignment_score: [1-10]
completeness_score: [1-10]
consistency_score: [1-10]
gaps_found:
- category: [category]
issue: [description]
severity: [high/medium/low]
recommendation: [how to address]
business_impact: [what business requirement this affects]
strong_areas:
- [what's well-defined]
trade_offs_review:
- decision: [decision]
assessment: [well-reasoned/needs-review/concerning]
notes: [additional context]
open_questions_assessment:
- question: [question]
blocking: [yes/no]
recommendation: [resolve now/later/accept uncertainty]
suggestions:
- [improvement suggestions]
ready_for_implementation: [yes/no/with-modifications]If critical gaps found (severity: high or blocking open questions), ask:
"I've identified some gaps in the technical requirements that could impact implementation. Would you like to:
>
1. Address them now (I'll ask follow-up questions)
2. Proceed to implementation planning (address during development)
3. Review the gaps and decide"
Next Steps
After completing the technical requirements interview and gap analysis:
1. Review gap analysis report 2. Address any critical gaps or blocking questions 3. Validate technical choices are realistic 4. Use /implementation-planner to generate implementation plans
Examples
See [references/example.yaml](references/example.yaml) for a complete sample output.
project: customer-portal-api
version: "2.0.0"
generated: "2026-04-15T10:30:00Z"
business_requirements_ref: ./business-requirements.yaml
overview: |
Customer Portal API service provides secure access to account data and transaction
history for end customers. Built as a REST API with JWT authentication, following
service-command architecture patterns for maintainability and testability.
Key features: Account queries, transaction history, document retrieval, notification
preferences. Designed for 100K+ active users with P95 response times under 500ms.
architecture:
pattern: Service-Command Architecture
description: |
Service organized around discrete command operations using @validkeys/contracted
for type-safe command definitions. Commands handle business logic and return
Result types (never throw exceptions).
**Architecture Components:**
1. **API Layer** (Fastify REST v2)
- Authentication middleware (JWT + refresh tokens)
- Request validation (Zod schemas)
- Error transformation
- OpenAPI documentation
2. **Service Layer** (d-modules/customer-portal)
- Command composition via defineService()
- Dependency injection
- Result type wrappers
3. **Command Layer** (src/commands/)
- Individual command implementations
- CFMV pattern (Context/Filters/Modifiers/Values)
- Business logic
- Repository delegation
4. **Repository Layer** (src/lib/repositories/)
- Database access abstraction
- Kysely query builder
- Transaction management
5. **PostgreSQL Database**
- Customer account data
- Transaction history
- Document metadata
- Notification preferences
**Key Benefits:**
- Clear separation of concerns
- Type-safe contracts
- Testable in isolation
- Easy to extend with new commands
components:
- name: API Layer
responsibility: HTTP interface, auth, validation, OpenAPI docs
- name: Service Layer
responsibility: Command composition and dependency injection
- name: Command Layer
responsibility: Business logic with Result types
- name: Repository Layer
responsibility: Database access and query optimization
- name: PostgreSQL Database
responsibility: Persistent data storage
patterns:
cfmv:
description: |
All commands follow CFMV (Context/Filters/Modifiers/Values) architecture patterns.
Query commands use CFM pattern:
- Context: RequestContext with customer_id from JWT
- Filters: Optional filtering criteria (account status, date ranges)
- Modifiers: Pagination, ordering, includes
Mutation commands use CV pattern:
- Context: RequestContext with customer_id from JWT
- Values: Data to update
examples:
- example_name: listTransactions
pattern: CFM
structure: |
{
context: RequestContext { customer_id: UUID },
filters: {
account_id: UUID,
transaction_type?: string,
start_date?: Date,
end_date?: Date
},
modifiers: {
page: number,
limit: number,
order_by: 'executed_at' | 'amount'
}
}
- example_name: updateNotificationPreferences
pattern: CV
structure: |
{
context: RequestContext { customer_id: UUID },
values: {
email_enabled?: boolean,
sms_enabled?: boolean,
push_enabled?: boolean,
frequency?: 'instant' | 'daily' | 'weekly'
}
}
technology_stack:
language: TypeScript
runtime: Node.js 20.x
frameworks:
- Fastify (REST API server)
- "@validkeys/contracted (service-command architecture)"
- Kysely (type-safe SQL query builder)
libraries:
core:
- zod (schema validation)
- neverthrow (Result type utilities)
- jsonwebtoken (JWT authentication)
- bcrypt (password hashing)
- pino (structured logging)
- "@spark/postgres (database connection)"
- "@spark/env (environment configuration)"
development:
- vitest (testing framework)
- "@types/node"
- typescript
- eslint
- prettier
- fastify-zod-openapi (OpenAPI generation)
package_manager: pnpm (monorepo)
project_structure:
type: monorepo
layout: |
d-modules/customer-portal/
├── src/
│ ├── commands/ # Command implementations
│ │ ├── listAccounts/ # Query commands
│ │ │ ├── index.ts # Command definition
│ │ │ └── index.test.ts # Command tests
│ │ ├── getAccount/
│ │ ├── listTransactions/
│ │ ├── getTransaction/
│ │ ├── listDocuments/
│ │ ├── getDocument/
│ │ ├── updateNotificationPreferences/ # Mutation commands
│ │ └── getNotificationPreferences/
│ ├── lib/
│ │ ├── repositories/ # Data access layer
│ │ │ ├── accounts/
│ │ │ │ ├── list.ts
│ │ │ │ ├── list.test.ts
│ │ │ │ ├── find-by-id.ts
│ │ │ │ └── find-by.ts
│ │ │ ├── transactions/
│ │ │ │ ├── list.ts
│ │ │ │ └── find-by-id.ts
│ │ │ ├── documents/
│ │ │ └── notifications/
│ │ └── utils/ # Shared utilities
│ │ ├── pagination.ts
│ │ └── filters.ts
│ ├── service.ts # Service composition
│ └── index.ts # Public exports
├── package.json
├── tsconfig.json
└── README.md
lib/contracts/src/domains/customerPortal/
├── commands/ # Command schemas
│ ├── listAccounts.ts
│ ├── getAccount.ts
│ ├── listTransactions.ts
│ └── ...
├── errors.ts # Error type definitions
├── types.ts # Shared types
└── index.ts # Barrel export
b-containers/customer-api/src/api/rest-v2/customer-portal/
├── index.ts # Fastify plugin
├── endpoints.ts # Route definitions
└── handlers/ # REST handlers
├── listAccounts/
│ ├── index.ts
│ └── schema.ts
└── ...
key_directories:
- path: d-modules/customer-portal/src/commands
purpose: Service commands using @validkeys/contracted
- path: d-modules/customer-portal/src/lib/repositories
purpose: Database access methods (internal implementation)
- path: lib/contracts/src/domains/customerPortal
purpose: Centralized schemas, types, and error definitions
- path: b-containers/customer-api/src/api/rest-v2/customer-portal
purpose: REST v2 HTTP endpoints
data_model:
strategy: PostgreSQL database (existing schema)
database: PostgreSQL 15.x (existing infrastructure)
schema_approach: |
Use existing PostgreSQL instance with schema 'customer_portal' for isolation.
No schema changes required - read-only access to existing tables.
**Tables:**
1. **customer_portal.accounts** (Primary account table)
- id: UUID PRIMARY KEY
- customer_id: UUID NOT NULL (indexed)
- account_number: VARCHAR(20) UNIQUE NOT NULL
- account_type: VARCHAR(50) NOT NULL
- status: VARCHAR(20) NOT NULL CHECK (status IN ('active', 'closed', 'suspended'))
- balance: DECIMAL(15, 2)
- currency: VARCHAR(3) DEFAULT 'USD'
- opened_at: TIMESTAMPTZ NOT NULL
- created_at: TIMESTAMPTZ DEFAULT NOW()
- updated_at: TIMESTAMPTZ DEFAULT NOW()
2. **customer_portal.transactions** (Transaction history)
- id: UUID PRIMARY KEY
- account_id: UUID REFERENCES customer_portal.accounts(id)
- transaction_type: VARCHAR(50) NOT NULL
- amount: DECIMAL(15, 2) NOT NULL
- currency: VARCHAR(3) DEFAULT 'USD'
- description: TEXT
- executed_at: TIMESTAMPTZ NOT NULL
- created_at: TIMESTAMPTZ DEFAULT NOW()
3. **customer_portal.documents** (Document metadata)
- id: UUID PRIMARY KEY
- customer_id: UUID NOT NULL (indexed)
- account_id: UUID (nullable)
- document_type: VARCHAR(100) NOT NULL
- file_path: TEXT NOT NULL
- generated_at: TIMESTAMPTZ NOT NULL
- created_at: TIMESTAMPTZ DEFAULT NOW()
4. **customer_portal.notification_preferences** (User preferences)
- id: UUID PRIMARY KEY
- customer_id: UUID UNIQUE NOT NULL
- email_enabled: BOOLEAN DEFAULT true
- sms_enabled: BOOLEAN DEFAULT false
- push_enabled: BOOLEAN DEFAULT true
- frequency: VARCHAR(20) DEFAULT 'daily'
- created_at: TIMESTAMPTZ DEFAULT NOW()
- updated_at: TIMESTAMPTZ DEFAULT NOW()
indexes:
customer_accounts:
index: idx_accounts_customer_id ON customer_portal.accounts(customer_id)
purpose: Fast lookup of all accounts for a customer
account_status:
index: idx_accounts_status ON customer_portal.accounts(status)
purpose: Filter by account status (active, closed, suspended)
transaction_account_date:
index: idx_transactions_account_executed ON customer_portal.transactions(account_id, executed_at DESC)
purpose: Transaction history queries with date ordering
customer_documents:
index: idx_documents_customer_id ON customer_portal.documents(customer_id, generated_at DESC)
purpose: Document list queries per customer
document_type:
index: idx_documents_type ON customer_portal.documents(document_type)
purpose: Filter documents by type
migrations: |
No migrations required - using existing database schema.
Read-only access via Kysely query builder.
api:
style: REST v2
framework: Fastify with fastify-zod-openapi
base_url: /api/v2/customer-portal
versioning: URL path versioning (/api/v2/)
documentation: OpenAPI 3.0 auto-generated from Zod schemas
endpoints:
# Account queries
- path: /listAccounts
method: POST
description: List all accounts for authenticated customer
auth: Required (JWT)
schema: ListAccountsRequestSchema / ListAccountsResponseSchema
- path: /getAccount
method: POST
description: Get detailed account information
auth: Required (JWT + account ownership verification)
schema: GetAccountRequestSchema / GetAccountResponseSchema
# Transaction queries
- path: /listTransactions
method: POST
description: List transactions for an account with pagination
auth: Required (JWT + account ownership verification)
schema: ListTransactionsRequestSchema / ListTransactionsResponseSchema
- path: /getTransaction
method: POST
description: Get detailed transaction information
auth: Required (JWT + account ownership verification)
schema: GetTransactionRequestSchema / GetTransactionResponseSchema
# Document queries
- path: /listDocuments
method: POST
description: List documents for customer
auth: Required (JWT)
schema: ListDocumentsRequestSchema / ListDocumentsResponseSchema
- path: /getDocument
method: POST
description: Get document metadata and signed download URL
auth: Required (JWT + document ownership verification)
schema: GetDocumentRequestSchema / GetDocumentResponseSchema
# Notification preferences
- path: /getNotificationPreferences
method: POST
description: Get customer notification preferences
auth: Required (JWT)
schema: GetNotificationPreferencesRequestSchema / GetNotificationPreferencesResponseSchema
- path: /updateNotificationPreferences
method: POST
description: Update customer notification preferences
auth: Required (JWT)
schema: UpdateNotificationPreferencesRequestSchema / UpdateNotificationPreferencesResponseSchema
security:
authentication:
method: JWT with refresh tokens
implementation: |
JWT-based authentication with short-lived access tokens (15 minutes)
and long-lived refresh tokens (7 days).
Flow:
1. User authenticates via /auth/login (separate auth service)
2. Receives access_token (JWT) and refresh_token
3. Access token includes: customer_id, email, issued_at, expires_at
4. All API requests require Bearer token in Authorization header
5. Expired tokens refreshed via /auth/refresh endpoint
JWT payload:
{
"sub": "customer_id (UUID)",
"email": "customer@example.com",
"iat": 1234567890,
"exp": 1234568790
}
authorization:
model: Context-based authorization (customer_id scoping)
implementation: |
All commands require authenticated customer context. Authorization
enforced via RequestContext pattern:
- Customer can only access their own accounts
- Account ownership verified on every request
- Database queries scoped by customer_id from JWT
- No admin or elevated permissions in this API
Enforcement:
1. JWT middleware extracts customer_id from token
2. RequestContext created with customer_id
3. Repository queries filtered by customer_id
4. Attempting to access other customers' data returns 404 Not Found
(not 403 Forbidden to avoid enumeration attacks)
secrets:
storage: Environment variables via @spark/env package
rotation: Quarterly rotation for JWT signing keys
secrets_required:
- JWT_SECRET (signing key for access tokens)
- JWT_REFRESH_SECRET (signing key for refresh tokens)
- DATABASE_URL (from @spark/postgres)
- S3_BUCKET_NAME (for document storage)
- AWS_ACCESS_KEY_ID (S3 access)
- AWS_SECRET_ACCESS_KEY (S3 access)
data_validation:
input: Zod schemas at API layer + command layer validation
output: Zod schemas validate command responses before returning
testing:
strategy: TDD with integration-focused approach
types:
unit:
framework: Vitest
coverage_target: 80% (focus on business logic)
scope: |
- Command implementations (input transformation, Result wrapping)
- CFMV schema validation
- Authorization logic
- Repository query builders
integration:
framework: Vitest with test database
approach: |
Test commands end-to-end against real PostgreSQL test database.
- Seed test data via fixtures
- Execute commands with realistic inputs
- Verify Result types and data correctness
- Test authorization boundaries
- Test pagination and filtering
coverage_target: 70%
e2e:
framework: Vitest + Fastify inject (no live HTTP)
approach: |
Test full API flows through Fastify routes:
- JWT authentication flow
- Account list and detail retrieval
- Transaction history with pagination
- Document access with signed URLs
- Notification preference updates
focus: |
- Authentication and authorization
- API contract compliance
- Error response formats
- OpenAPI schema validation
mocking:
strategy: |
Mock external dependencies (S3 for documents), use real database
for repository tests. Mock database only for command unit tests.
tools:
- Vitest mock functions
- Test database with seed data
- S3 mock via aws-sdk-mock
development:
workflow: |
1. Local development with Docker Compose (PostgreSQL test instance)
2. Feature branch workflow (main → feature → PR → main)
3. Use @spark/postgres for database connection
4. Hot reload via Fastify plugin in development mode
5. OpenAPI docs available at /docs in development
code_quality:
linter: ESLint (monorepo config)
formatter: Prettier (monorepo config)
type_checker: TypeScript strict mode
pre_commit_hooks:
- ESLint --fix on staged files
- Prettier --write on staged files
- TypeScript type check (tsc --noEmit)
- Vitest related tests
ci_cd:
platform: GitHub Actions (existing monorepo CI/CD)
pipeline:
- stage: Validate
actions:
- Install dependencies (pnpm install)
- Type check (tsc --noEmit)
- Lint (eslint)
- Unit tests (vitest unit)
- Integration tests (vitest integration)
- stage: Build
actions:
- Build service package (turbo build --filter=@spark/customer-portal)
- Build affected packages
- Generate OpenAPI documentation
- stage: Deploy to Staging
actions:
- Deploy to staging environment
- Run E2E tests against staging
- Run smoke tests
- stage: Deploy to Production
actions:
- Manual approval required
- Blue-green deployment to production
- Run production smoke tests
- Monitor error rates for 30 minutes
- Automatic rollback on error spike
operations:
deployment:
target: Kubernetes (existing infrastructure)
packaging:
format: Docker image (Fastify application)
distribution: ECR (Elastic Container Registry)
environments:
- name: development
config: |
- Kubernetes namespace: customer-portal-dev
- Database: customer_portal schema on dev instance
- JWT_SECRET: dev secret (not for production use)
- S3 bucket: customer-documents-dev
- Logging: debug level
- name: staging
config: |
- Kubernetes namespace: customer-portal-staging
- Database: customer_portal schema on staging instance
- JWT_SECRET: staging secret (rotated quarterly)
- S3 bucket: customer-documents-staging
- Logging: info level
- name: production
config: |
- Kubernetes namespace: customer-portal-prod
- Database: customer_portal schema on prod instance
- JWT_SECRET: production secret (rotated quarterly)
- S3 bucket: customer-documents-prod
- Logging: warn level (errors always logged)
- Horizontal Pod Autoscaler (HPA): 3-10 replicas
- Resource limits: 1 CPU, 2GB memory per pod
release_process:
strategy: Semantic Versioning (SemVer)
automation: |
Fully automated via GitHub Actions:
1. Merge to main branch triggers CI/CD
2. Automated deployment to staging
3. Automated E2E tests on staging
4. Manual approval gate for production
5. Blue-green deployment to production
6. Automated smoke tests
7. Automatic rollback on failure
monitoring:
logging:
format: Structured JSON (pino logger)
destination: Kubernetes logs → CloudWatch Logs
levels: |
- debug: Development only, request/response details
- info: Request logs, successful operations
- warn: Deprecations, non-blocking issues
- error: Errors, exceptions, failures
metrics:
collection: Prometheus (existing infrastructure)
visualization: Grafana dashboards
key_metrics:
- api_request_duration_seconds (histogram by endpoint)
- api_request_total (counter by endpoint and status)
- database_query_duration_seconds (histogram by query type)
- jwt_validation_duration_seconds (histogram)
- active_customer_sessions (gauge)
alerts:
strategy: |
Alert on:
- Error rate > 1% over 5-minute window
- P95 response time > 1 second
- Database connection pool exhaustion
- JWT validation failures > 5% (potential attack)
channels:
- Slack #customer-portal-alerts channel
- PagerDuty for critical alerts (production only)
performance:
targets:
response_time: P95 < 500ms, P99 < 1000ms
throughput: 5000 requests/minute sustained, 10K requests/minute peak
optimization:
strategy: |
- Database connection pooling (max 50 connections per pod)
- Query optimization with proper indexes
- Pagination for all list endpoints (default 50, max 200)
- Zod schema compilation and caching
- Fastify serialization optimization
- No N+1 queries (use joins or batch queries)
- JWT signature verification caching (5-minute TTL)
monitoring: |
Continuous monitoring via Grafana dashboards:
- Response time percentiles (P50, P95, P99)
- Database query performance
- Connection pool utilization
- Memory and CPU usage per pod
scalability:
approach: Horizontal scaling via Kubernetes HPA
limits:
concurrent_users: 100K+ (designed for scale)
data_volume: 10M+ transactions, 1M+ customers
bottlenecks:
- Database connection pool (mitigated with proper sizing)
- Transaction history queries for high-volume accounts (mitigated with pagination + indexes)
- JWT signature verification CPU usage (mitigated with caching)
feature_flags:
strategy: Gradual rollout with instant rollback capability
system: Statsig
flags:
- flag_id: customer_portal_api
name: feature.customer_portal.api_access
description: |
Controls access to the new Customer Portal API. When disabled, API returns
503 Service Unavailable. When enabled, customers can access account data
via the new API endpoints.
Disabled behavior (default):
- API returns 503 with maintenance message
- Customers directed to legacy portal
Enabled behavior:
- Full API access with JWT authentication
- All endpoints functional
default_state: false
rollout_strategy:
phases:
- name: Internal Testing
target: Internal test users
percentage: 1-2%
duration: 1 week
- name: Early Adopters
target: Selected customers
percentage: 10%
duration: 1 week
- name: Gradual Rollout
target: All customers
percentage: 25% → 50% → 100%
duration: 2 weeks
- name: Stabilization
target: All customers
percentage: 100%
duration: 30 days
- name: Cleanup
target: Remove flag code
percentage: N/A
duration: 1 week
cleanup_timeline: 30 days at 100% with no critical issues
monitoring:
- API error rate by flag state (enabled vs disabled)
- Response time percentiles by flag state
- JWT validation success rate
- Customer adoption rate (API usage vs legacy)
integration_points:
- location: b-containers/customer-api/src/middleware/feature-flag.ts
purpose: API-level kill switch - returns 503 when disabled
- location: apps/customer-webapp/src/hooks/useCustomerPortalAccess.ts
purpose: UI visibility - show/hide new portal features
- location: lib/kitchen-sink/src/statsig/feature-gates.ts
purpose: Feature gate enum definition
constraints:
technical:
- Must use TypeScript with strict mode
- Must use @validkeys/contracted for service-command architecture
- Must use existing PostgreSQL database (read-only access)
- Must follow REST v2 patterns from existing APIs
- Must use existing authentication service (no auth logic in this API)
- Must centralize schemas in @spark/contracts
- JWT tokens must be short-lived (15-minute max)
operational:
- 6-week timeline for MVP
- Team of 3 developers
- Read-only access to customer data (no mutations except preferences)
- Must support 100K+ active users from day one
- Production deployment requires security review
architectural:
- Must follow monorepo naming conventions (d-modules/customer-portal)
- Repository methods must be internal to service
- Must expose via REST v2 at /api/v2/customer-portal
- Must generate OpenAPI documentation
trade_offs:
- decision: JWT with short expiration vs session-based auth
rationale: |
Stateless authentication scales better, no session storage required,
works across multiple API instances without sticky sessions.
alternative: Session-based authentication with Redis
consequence: |
Requires refresh token mechanism for mobile apps, JWT cannot be
invalidated before expiration (mitigated with short expiration).
reversibility: Low - authentication is foundational decision
- decision: Read-only API vs full CRUD
rationale: |
Aligns with business requirements (view-only portal), reduces complexity,
eliminates audit trail requirements, faster time to market.
alternative: Full CRUD API with audit logging
consequence: |
Cannot modify account data via API (future feature if needed).
Notification preferences are only mutation allowed.
reversibility: Medium - can add mutations later if needed
- decision: Context-based authorization vs RBAC
rationale: |
Simpler model for single-tenant customer access, customers can only
access their own data. No roles or permissions needed.
alternative: RBAC with customer/admin roles
consequence: |
No admin access via this API (separate ops tools for admin functions).
reversibility: Medium - can layer RBAC on top later
- decision: Repository layer internal to service vs shared package
rationale: |
Service owns its data access, can evolve independently, clear
encapsulation boundaries.
alternative: Shared repository package in e-framework/data
consequence: |
Cannot reuse repositories across services (intentional isolation).
reversibility: Medium - can extract if reuse becomes necessary
open_questions:
- question: Should we support CSV export for transaction history?
options:
- "No - keep API simple, defer to future enhancement"
- "Yes - add /exportTransactions endpoint with async job pattern"
impact: API surface area, implementation complexity, timeline
recommendation: Defer to Phase 2, validate user demand first
decision: Deferred to Phase 2
- question: How to handle document download authentication?
options:
- "Signed S3 URLs with 1-hour expiration (recommended)"
- "Proxy downloads through API (higher bandwidth cost)"
impact: Security, cost, API performance
recommendation: Signed S3 URLs for security and cost efficiency
decision: Signed S3 URLs with 1-hour expiration
implementation_priorities:
phase_1_weeks_1_2:
- Set up d-modules/customer-portal package structure
- Create lib/contracts/src/domains/customerPortal with Zod schemas
- Implement repository layer (accounts, transactions, documents, notifications)
- Write repository tests with test database
- Create command definitions using @validkeys/contracted
phase_2_weeks_3_4:
- Implement account commands (listAccounts, getAccount)
- Implement transaction commands (listTransactions, getTransaction)
- Implement document commands (listDocuments, getDocument)
- Implement notification commands (get/update preferences)
- Unit tests for all commands
- Integration tests with test database
phase_3_weeks_5_6:
- Create REST v2 endpoints in b-containers/customer-api
- Implement JWT authentication middleware
- Implement authorization middleware
- Generate OpenAPI documentation
- E2E tests via Fastify inject
- Security review and hardening
- Production deployment
success_criteria:
- criterion: API responds within performance targets
metric: P95 response time
target: < 500ms
- criterion: API handles expected load
metric: Sustained throughput
target: 5000 requests/minute
- criterion: Zero unauthorized data access
metric: Authorization test pass rate
target: 100%
- criterion: API contract completeness
metric: OpenAPI schema coverage
target: 100% of endpoints documented
- criterion: Test coverage meets targets
metric: Code coverage
target: "> 80% (unit), > 70% (integration)"
implementation_notes:
- Reference service-command architecture specification in monorepo docs
- Follow existing REST v2 patterns from IAM service
- JWT middleware already exists in b-containers/customer-api, reuse it
- Use existing @spark/postgres connection pooling patterns
- S3 signed URL generation in lib/aws-utils package
- Authorization pattern: lib/kitchen-sink/src/auth/context-based-auth.ts
- OpenAPI generation: existing Fastify plugin configuration
next_steps:
- Review technical requirements with stakeholders
- Security team review of authentication/authorization approach
- DBA review of database indexes and query patterns
- Use /implementation-planner to generate detailed milestones and tasks
- Begin Phase 1: Package setup and repository layer implementation
Technical Interview JSONL Specification
Document Overview
Purpose
The Technical Interview JSONL file tracks question-answer pairs during the interactive /technical-requirements-interview skill. Each line represents one completed technical interview exchange, enabling resume capability and preserving the interview transcript.
Role in Workflow
- Phase: Requirements (Step 3 of Sherpy Flow)
- Generated By:
/technical-requirements-interviewskill (incremental, line-by-line) - Input Dependencies: business-requirements.yaml (loaded as context for interview questions)
- Output Consumers:
/technical-requirements-interview(resume logic), technical-requirements.yaml (generated from completed interview)
When to Use
- Automatically created when technical interview begins
- Appended to after each question is answered
- Read on resume to determine last completed question
- Archived as interview transcript after technical-requirements.yaml generation
---
File Format & Location
File Details
- Filename:
technical-interview.jsonl - Format: JSONL (JSON Lines - newline-delimited JSON objects)
- Location:
{base_directory}/artifacts/technical-interview.jsonl - Character Encoding: UTF-8
- Line Endings: LF (
\n) - each JSON object on exactly one line
Directory Structure
{base_directory}/
└── artifacts/
├── business-interview.jsonl
└── technical-interview.jsonlJSONL Format Rules
- One complete JSON object per line
- No trailing commas in objects
- No line breaks within JSON objects
- Each line ends with
\n - Empty lines are not allowed
- File may be empty (0 bytes) initially
---
JSONL Schema Definition
Line Format
Each line is a JSON object with these fields:
{
"id": integer, // Sequential question number (1-based)
"category": string, // Technical category name
"question": string, // Question text presented to user
"answer": string, // User's answer (may be multi-line)
"question_number": string, // Display label (e.g., "Q1", "Q2")
"timestamp": string // ISO 8601 timestamp (with timezone)
}Complete Example
{"id":1,"category":"Architecture & Patterns","question":"What architecture pattern best fits this project?","answer":"Monolithic application - Single deployable unit, simpler to develop and deploy initially","question_number":"Q1","timestamp":"2025-01-27T11:00:00Z"}
{"id":2,"category":"Technology Stack","question":"Which programming language should be used?","answer":"TypeScript - Type-safe JavaScript, excellent tooling, large ecosystem","question_number":"Q2","timestamp":"2025-01-27T11:05:00Z"}
{"id":3,"category":"Data Model & Storage","question":"What data persistence strategy is appropriate?","answer":"File-based storage - Simple, portable, no database dependency. We'll use YAML files for workflow definitions and JSON for execution state.","question_number":"Q3","timestamp":"2025-01-27T11:12:30Z"}---
Field Definitions
| Field | Type | Required | Constraints | Description |
|---|---|---|---|---|
| id | integer | Yes | >= 1, sequential | Sequential question number starting at 1 |
| category | string | Yes | Non-empty | Technical interview category (see Standard Categories) |
| question | string | Yes | Non-empty | Question text as presented to user |
| answer | string | Yes | Non-empty | User's complete answer |
| question_number | string | Yes | Format: "Q{id}" | Display label matching ID |
| timestamp | string | Yes | ISO 8601 with timezone | When answer was recorded |
Standard Categories
These match the technical-requirements-interview skill structure:
1. Architecture & Patterns - Architecture style, component organization 2. Technology Stack - Language, frameworks, libraries, package manager 3. Project Structure - Monorepo vs. multi-repo, directory layout 4. Data Model & Storage - Persistence strategy, database, schema design 5. API Design - API style (REST/GraphQL/RPC/CLI), framework, versioning 6. Security & Authentication - Auth method, authorization, secrets management 7. Testing Strategy - Testing approach, test types, frameworks 8. Development & Tooling - Workflow, code quality tools, pre-commit hooks 9. CI/CD - CI/CD platform, pipeline stages 10. Deployment & Distribution - Deployment target, packaging, release process 11. Monitoring & Observability - Logging, metrics, alerts 12. Performance - Performance targets, optimization strategies 13. Scalability - Scaling approach, limits, bottlenecks
Timestamp Format
- Must be ISO 8601 format:
YYYY-MM-DDTHH:MM:SSZorYYYY-MM-DDTHH:MM:SS±HH:MM - Examples:
2025-01-27T11:00:00Z(UTC)2025-01-27T11:00:00-05:00(EST)2025-01-27T16:45:22.789Z(UTC with milliseconds)
Question Number Format
- Must match pattern:
Q{id} - Examples:
"Q1","Q2","Q15","Q100" - Must be consistent with
idfield: ifidis 5,question_numbermust be"Q5"
Answer Field Rules
- Multi-line answers must use JSON string escaping (
\nfor newlines) - Quotes within answers must be escaped (
\") - May contain markdown formatting if user provided it
- Typically includes option number prefix if user selected a numbered option
- Often includes extended explanation beyond the option text
- Example:
"Option 1 - TypeScript (Recommended). We'll use strict mode for type safety and leverage the rich ecosystem of TypeScript tooling including ts-node for development."
---
Validation Rules
File-Level Validation
- [ ] File is valid JSONL (one JSON object per line)
- [ ] No empty lines
- [ ] All lines end with
\n(including last line) - [ ] File uses UTF-8 encoding
- [ ] Each line parses as valid JSON object
Structural Validation
- [ ] Each object has all 6 required fields
- [ ] No extra fields present
- [ ] All field types match schema
- [ ] IDs are sequential integers starting at 1
- [ ] No duplicate IDs
Content Validation
- [ ] All strings are non-empty
- [ ] IDs start at 1 and increment by 1
- [ ] No gaps in ID sequence
- [ ] Timestamps are valid ISO 8601 format
- [ ] Timestamps are in chronological order
- [ ] Category names match standard list
- [ ] Questions are unique (no exact duplicates)
- [ ]
question_numbermatchesid:question_number === "Q" + id
Resume Validation
When resuming an interview:
- [ ] Last line has valid JSON with all required fields
- [ ] Next question ID should be
max_id + 1 - [ ] File integrity check: all IDs from 1 to max_id exist
- [ ] Question numbers are consistent with IDs
---
Generation Guidelines
Initial Creation
When starting a new technical interview: 1. Verify {base_directory}/requirements/business-requirements.yaml exists (prerequisite) 2. Check if {base_directory}/artifacts/technical-interview.jsonl exists 3. If not, create empty file (0 bytes) or create on first append 4. Ensure parent directory exists: mkdir -p {base_directory}/artifacts
Appending Q&A Pairs
After each user answer: 1. Create JSON object with all 6 required fields 2. Generate ISO 8601 timestamp at answer recording time 3. Set question_number to "Q" + id 4. Serialize to single-line JSON (no pretty-printing) 5. Append line + \n to file 6. Do not add blank lines or comments
Example Append Sequence
// After user answers question 1
const qa1 = {
id: 1,
category: "Architecture & Patterns",
question: "What architecture pattern best fits this project?",
answer: "Monolithic application - Single deployable unit, simpler to develop",
question_number: "Q1",
timestamp: new Date().toISOString()
};
fs.appendFileSync(path, JSON.stringify(qa1) + '\n');
// After user answers question 2
const qa2 = {
id: 2,
category: "Technology Stack",
question: "Which programming language should be used?",
answer: "TypeScript - Type-safe JavaScript with excellent tooling",
question_number: "Q2",
timestamp: new Date().toISOString()
};
fs.appendFileSync(path, JSON.stringify(qa2) + '\n');Resume Logic
When resuming an interrupted technical interview:
1. Read Existing File
const lines = fs.readFileSync(path, 'utf-8').trim().split('\n').filter(Boolean);
const completed = lines.map(line => JSON.parse(line));2. Determine Last Completed Question
const lastId = completed.length > 0 ? Math.max(...completed.map(q => q.id)) : 0;
const nextId = lastId + 1;
const nextQuestionNumber = `Q${nextId}`;3. Validate Sequence
// Ensure no gaps in IDs
for (let i = 1; i <= lastId; i++) {
if (!completed.find(q => q.id === i)) {
throw new Error(`Gap detected: Question ${i} is missing`);
}
}
// Validate question_number consistency
completed.forEach(q => {
const expected = `Q${q.id}`;
if (q.question_number !== expected) {
throw new Error(`Question ${q.id}: expected ${expected}, got ${q.question_number}`);
}
});4. Display Resume Message
Found existing technical interview with 8 completed questions.
Loaded business requirements from business-requirements.yaml.
Resuming from question Q9...5. Continue Interview
- Skip questions with IDs 1-8
- Start with question ID 9 (question_number "Q9")
- Continue appending as normal
Context Loading
Before starting or resuming: 1. Load {base_directory}/requirements/business-requirements.yaml 2. Parse business requirements to understand project context 3. Use business context to inform technical question phrasing 4. Reference business requirements when providing answer options
Example:
const businessReqs = yaml.parse(
fs.readFileSync(`${baseDir}/requirements/business-requirements.yaml`, 'utf-8')
);
// Use in question text
const question = `Given that your target users are ${businessReqs.personas[0].name},
which deployment strategy makes sense?`;---
Usage Examples
Example 1: First Three Technical Questions
{"id":1,"category":"Architecture & Patterns","question":"What architecture pattern best fits this project?","answer":"Monolithic application - Single deployable unit, simpler to develop and deploy initially. Given the CLI nature and solo developer constraint, monolithic makes sense.","question_number":"Q1","timestamp":"2025-01-27T11:00:00Z"}
{"id":2,"category":"Technology Stack","question":"Which programming language should be used?","answer":"TypeScript (Recommended) - Type-safe JavaScript, excellent tooling, large ecosystem. We need the Node.js runtime compatibility and TypeScript will help catch bugs early.","question_number":"Q2","timestamp":"2025-01-27T11:05:18Z"}
{"id":3,"category":"Project Structure","question":"What project structure approach is best?","answer":"Single repository with organized directories. Structure:\nsrc/ - source code\ntests/ - test files\ndocs/ - documentation\nconfig/ - configuration files","question_number":"Q3","timestamp":"2025-01-27T11:10:42Z"}Example 2: Security & Testing Questions
{"id":7,"category":"Security & Authentication","question":"What authentication method is required?","answer":"None - This is a local CLI tool with file-based storage. No network authentication needed. File system permissions provide security.","question_number":"Q7","timestamp":"2025-01-27T11:28:15Z"}
{"id":8,"category":"Testing Strategy","question":"What testing approach should be used?","answer":"TDD with Jest. Unit tests for core logic (80% coverage target), integration tests for workflow execution, and manual testing for CLI UX. No E2E framework needed since it's a CLI tool.","question_number":"Q8","timestamp":"2025-01-27T11:33:50Z"}Example 3: Answer with Technical Details
{"id":4,"category":"Data Model & Storage","question":"What data persistence strategy is appropriate?","answer":"File-based storage (Recommended) - Simple, portable, no database dependency. We'll use:\n- YAML files for workflow definitions (user-editable)\n- JSON files for execution state and logs\n- File watching for hot-reload during development\n- No migrations needed since schema is in code\nThis aligns with the 'works offline' constraint from business requirements.","question_number":"Q4","timestamp":"2025-01-27T11:15:30Z"}Example 4: Complete Technical Interview Session
{"id":1,"category":"Architecture & Patterns","question":"What architecture pattern best fits this project?","answer":"Monolithic CLI application","question_number":"Q1","timestamp":"2025-01-27T11:00:00Z"}
{"id":2,"category":"Technology Stack","question":"Which programming language?","answer":"TypeScript","question_number":"Q2","timestamp":"2025-01-27T11:05:00Z"}
{"id":3,"category":"Data Model & Storage","question":"Data persistence strategy?","answer":"File-based YAML and JSON","question_number":"Q3","timestamp":"2025-01-27T11:10:00Z"}
{"id":4,"category":"API Design","question":"What API style?","answer":"CLI commands with subcommands (init, run, validate)","question_number":"Q4","timestamp":"2025-01-27T11:15:00Z"}
{"id":5,"category":"Testing Strategy","question":"Testing approach?","answer":"TDD with Jest, 80% unit coverage","question_number":"Q5","timestamp":"2025-01-27T11:20:00Z"}
{"id":6,"category":"Deployment & Distribution","question":"Distribution method?","answer":"npm package published to registry","question_number":"Q6","timestamp":"2025-01-27T11:25:00Z"}---
Error Handling
Common Errors and Recovery
Corrupted File
Error: Last line is invalid JSON Recovery: 1. Read file up to last valid line 2. Truncate file to remove corrupted line 3. Resume from last valid ID 4. Log warning about data loss
Duplicate IDs
Error: Two lines have same ID Recovery: 1. Keep first occurrence 2. Renumber subsequent lines sequentially 3. Update question_number to match new IDs 4. Log warning about duplicates removed
Missing IDs
Error: Gap in sequence (e.g., 1, 2, 4, 5) Recovery: 1. If gap is at end: continue from max_id + 1 2. If gap is in middle: data corruption, cannot auto-fix 3. Prompt user to either restart interview or manually fix file
Inconsistent Question Numbers
Error: question_number doesn't match id (e.g., id=5 but question_number="Q3") Recovery: 1. Auto-fix by regenerating question_number from id 2. Log warning about inconsistency corrected 3. Continue with corrected values
Empty Answer
Error: Answer field is empty string Recovery:
- Do not append line to file
- Re-ask the same question
- Explain that answers cannot be empty
Missing Business Requirements
Error: business-requirements.yaml not found Recovery:
- Halt interview with clear error message
- Instruct user to run
/business-requirements-interviewfirst - Cannot proceed without business context
---
Integration Points
With technical-requirements-interview Skill
Start of Interview:
// Load business requirements (prerequisite)
const businessReqsPath = path.join(baseDir, 'requirements', 'business-requirements.yaml');
if (!fs.existsSync(businessReqsPath)) {
throw new Error('business-requirements.yaml not found. Run /business-requirements-interview first.');
}
const businessReqs = yaml.parse(fs.readFileSync(businessReqsPath, 'utf-8'));
// Check for existing interview
const interviewPath = path.join(baseDir, 'artifacts', 'technical-interview.jsonl');
if (fs.existsSync(interviewPath)) {
const completed = readCompletedQuestions(interviewPath);
console.log(`Found ${completed.length} completed technical questions. Resuming...`);
startFromQuestionId = completed.length + 1;
} else {
startFromQuestionId = 1;
}After Each Answer:
const qa = {
id: currentQuestionId,
category: currentCategory,
question: questionText,
answer: userAnswer,
question_number: `Q${currentQuestionId}`,
timestamp: new Date().toISOString()
};
appendToJSONL(interviewPath, qa);Interview Completion:
// Generate technical-requirements.yaml from JSONL
const allAnswers = readAllAnswers(interviewPath);
const technicalReqs = transformToTechnicalRequirements(allAnswers, businessReqs);
writeYAML(requirementsPath, technicalReqs);
console.log(`Technical interview complete. Transcript saved to ${interviewPath}`);
console.log(`Generated ${requirementsPath}`);With technical-requirements.yaml
The completed JSONL file is the source for generating technical-requirements.yaml:
Transformation Logic: 1. Read all Q&A pairs from JSONL 2. Group by category 3. Map categories to technical-requirements.yaml sections:
- "Architecture & Patterns" →
architecturesection - "Technology Stack" →
technology_stacksection - "Data Model & Storage" →
data_modelsection - "API Design" →
apisection - etc.
4. Parse answers to extract structured data 5. Apply business requirements context (e.g., constraints, timeline) 6. Generate complete technical-requirements.yaml
Example Mapping:
// From JSONL
{
"id": 1,
"category": "Technology Stack",
"question": "Which programming language?",
"answer": "TypeScript - Type-safe JavaScript with excellent tooling",
"question_number": "Q1",
"timestamp": "2025-01-27T11:00:00Z"
}
// To technical-requirements.yaml
technology_stack:
language: TypeScript
runtime: Node.js
rationale: |
Type-safe JavaScript with excellent tooling ecosystem.
Chosen for type safety, IDE support, and large community.With business-requirements.yaml
Technical interview questions reference business requirements:
Context Usage:
- User personas inform deployment/distribution questions
- Constraints (timeline, budget) inform technology stack options
- Functional requirements guide architecture pattern recommendations
- Success criteria influence performance/scalability questions
Example:
// Business requirement
const persona = businessReqs.personas[0]; // "Solo Developer"
// Influences technical question
const question = `Given your target user is ${persona.name} (${persona.description}),
which deployment approach makes sense?`;
const options = [
"npm package - Easy for developers to install globally",
"Docker container - Consistent environment but overhead",
"Binary distribution - Fast but complex build process"
];---
Archival and Cleanup
Archival Strategy
After technical-requirements.yaml is generated:
- Keep
technical-interview.jsonlinartifacts/as interview transcript - Useful for understanding technical decision rationale
- Can be referenced if architecture decisions are questioned
- Provides audit trail of why technologies were chosen
Retention:
- Permanent (part of project documentation)
- Include in version control for full history
- Compress if file size is concern (gzip reduces 70-80%)
Cleanup Guidelines
Do NOT delete if:
- Interview is incomplete
- Resume capability is needed
- Generated technical-requirements.yaml hasn't been reviewed
- Architecture decisions may need justification
Safe to archive/compress if:
- technical-requirements.yaml is complete and reviewed
- Architecture decisions are documented in ADRs
- Project is in later phases (implementation, deployment)
- Need to reduce repo size
---
Conversion Utilities
Convert to Markdown
# Future CLI utility
sherpy convert technical-interview.jsonl --to markdownOutput Format:
# Technical Requirements Interview Transcript
**Project:** task-automation-cli
**Completed:** 2025-01-27
**Questions:** 15
**Business Requirements:** business-requirements.yaml
---
## Architecture & Patterns
### Question Q1
**Q:** What architecture pattern best fits this project?
**A:** Monolithic application - Single deployable unit, simpler to develop and deploy initially
**Timestamp:** 2025-01-27T11:00:00Z
---
## Technology Stack
### Question Q2
**Q:** Which programming language should be used?
**A:** TypeScript - Type-safe JavaScript, excellent tooling, large ecosystem
**Timestamp:** 2025-01-27T11:05:00ZConvert to Decision Log
# Extract key decisions
sherpy convert technical-interview.jsonl --to decisionsOutput Format:
# Technical Decisions
1. **Architecture:** Monolithic application
- Rationale: Single deployable unit, simpler for MVP
- Date: 2025-01-27
2. **Language:** TypeScript
- Rationale: Type safety, tooling, ecosystem
- Date: 2025-01-27
3. **Data Storage:** File-based (YAML/JSON)
- Rationale: Simple, portable, no database dependency
- Date: 2025-01-27---
Testing and Validation Script
Validation Script
function validateTechnicalInterviewJSONL(filePath) {
const lines = fs.readFileSync(filePath, 'utf-8').trim().split('\n');
const errors = [];
const ids = new Set();
lines.forEach((line, idx) => {
const lineNum = idx + 1;
// Parse check
let obj;
try {
obj = JSON.parse(line);
} catch (e) {
errors.push(`Line ${lineNum}: Invalid JSON`);
return;
}
// Required fields (6 fields for technical interview)
const required = ['id', 'category', 'question', 'answer', 'question_number', 'timestamp'];
for (const field of required) {
if (!(field in obj)) {
errors.push(`Line ${lineNum}: Missing field '${field}'`);
}
}
// Type checks
if (typeof obj.id !== 'number' || obj.id < 1) {
errors.push(`Line ${lineNum}: 'id' must be positive integer`);
}
if (typeof obj.category !== 'string' || !obj.category) {
errors.push(`Line ${lineNum}: 'category' must be non-empty string`);
}
if (typeof obj.question !== 'string' || !obj.question) {
errors.push(`Line ${lineNum}: 'question' must be non-empty string`);
}
if (typeof obj.answer !== 'string' || !obj.answer) {
errors.push(`Line ${lineNum}: 'answer' must be non-empty string`);
}
if (typeof obj.question_number !== 'string' || !obj.question_number) {
errors.push(`Line ${lineNum}: 'question_number' must be non-empty string`);
}
// question_number format and consistency check
const expectedQNum = `Q${obj.id}`;
if (obj.question_number !== expectedQNum) {
errors.push(`Line ${lineNum}: 'question_number' should be '${expectedQNum}', got '${obj.question_number}'`);
}
// Timestamp validation
if (typeof obj.timestamp === 'string') {
const date = new Date(obj.timestamp);
if (isNaN(date.getTime())) {
errors.push(`Line ${lineNum}: Invalid ISO 8601 timestamp`);
}
} else {
errors.push(`Line ${lineNum}: 'timestamp' must be string`);
}
// Duplicate ID check
if (ids.has(obj.id)) {
errors.push(`Line ${lineNum}: Duplicate ID ${obj.id}`);
}
ids.add(obj.id);
});
// Sequential ID check
const sortedIds = Array.from(ids).sort((a, b) => a - b);
for (let i = 0; i < sortedIds.length; i++) {
if (sortedIds[i] !== i + 1) {
errors.push(`ID sequence gap: expected ${i + 1}, found ${sortedIds[i]}`);
break;
}
}
return errors;
}
// Usage
const errors = validateTechnicalInterviewJSONL('artifacts/technical-interview.jsonl');
if (errors.length === 0) {
console.log('✓ Technical interview JSONL is valid');
} else {
console.error('✗ Validation errors:');
errors.forEach(err => console.error(` - ${err}`));
process.exit(1);
}---
Differences from business-interview.jsonl
Additional Field
Technical interview includes `question_number` field:
{
"id": 3,
"question_number": "Q3", // ← Additional field
"category": "Data Model & Storage",
"question": "...",
"answer": "...",
"timestamp": "..."
}Business interview has only 5 fields (no question_number):
{
"id": 3,
"category": "Scope Definition",
"question": "...",
"answer": "...",
"timestamp": "..."
}Category Differences
Technical categories are more technical/implementation-focused:
- Architecture & Patterns
- Technology Stack
- Data Model & Storage
- API Design
- Security & Authentication
- Testing Strategy
- CI/CD
Business categories are more business/product-focused:
- Problem Definition
- User Personas
- Functional Requirements
- Success Criteria
- Constraints
Context Requirements
Technical interview requires business-requirements.yaml:
- Must exist before starting technical interview
- Loaded as context to inform technical questions
- Referenced when providing answer options
Business interview has no prerequisites:
- Can start from scratch or from gap-analysis-worksheet.yaml
- No other documents required
---
Related Documents
- Input: business-requirements.yaml (prerequisite for context)
- Generated By:
/technical-requirements-interviewskill - Output Consumer: technical-requirements.yaml (via interview skill)
- Parallel Artifact: business-interview.jsonl (same format pattern)
- Workflow Position: Step 3 of Sherpy Flow (after business requirements, before implementation planning)
---
Version History
| Version | Date | Changes |
|---|---|---|
| 1.0 | 2026-04-16 | Initial specification - JSONL format with question_number field |
Technical Requirements Specification (technical-requirements.yaml)
Document Type: YAML (strict structure) Purpose: Capture technical implementation details derived from business requirements Generated By: /technical-requirements-interview skill Consumers: Implementation planner, development teams, architecture review Location: {base_directory}/requirements/technical-requirements.yaml
---
Overview
The technical requirements document translates business needs into actionable technical specifications. It captures architectural decisions, technology stack choices, data models, API design, security requirements, and operational considerations. Generated through a structured interview process that ensures alignment with business requirements and technical constraints.
Schema Version: 2.0.0 (Consolidated structure)
---
Schema Structure
Metadata Section
project: string # Project name (kebab-case)
version: string # Schema version (e.g., "2.0.0")
generated: string # ISO 8601 timestamp
business_requirements_ref: string # Relative path to business-requirements.yamlField Descriptions:
- project: Technical project identifier, should match business requirements
- version: Schema version, increment for major structural changes
- generated: Interview completion timestamp
- business_requirements_ref: Path to source business requirements (e.g.,
./business-requirements.yaml)
Validation Rules:
projectmust be valid kebab-case identifierversionmust follow semver pattern (major.minor.patch)generatedmust be valid ISO 8601 datetimebusiness_requirements_refmust be valid relative path
---
Optional: Overview Section
overview: |
Multi-line string providing high-level technical summary.Purpose: Executive summary of technical approach When to Include: Complex projects with multiple components or when technical scope needs context Content Guidelines:
- Brief project summary from technical perspective
- Key architectural principles
- Major technical decisions at a glance
- 3-5 paragraphs maximum
---
Architecture Section
architecture:
pattern: string # Architecture pattern name
description: | # Multi-line description
Detailed explanation of architecture approach
components: # List of major components
- name: string # Component name
responsibility: string # What it does
# Optional: Architectural patterns
patterns: # Specific patterns used
pattern_name: # Pattern identifier (cfmv, saga, cqrs)
description: | # Pattern explanation
How this pattern is applied
examples: # Pattern examples (optional)
- example_name: string
structure: |
Example structure
# Optional: Workflow orchestration
workflow_orchestration: # Durable execution systems
system: string # Temporal, Cadence, Step Functions
configuration: # System-specific config
task_queue: string # Optional
namespace: string # Optional
timeouts: {} # Optional
retry_policy: {} # Optional
workflows: # Workflow definitions
workflow_name:
description: |
What this workflow orchestrates
steps: [] # Optional
signals: [] # OptionalField Descriptions:
- pattern: Architecture style (e.g., "Monolithic", "Microservices", "Service-Command", "Event-driven")
- description: Comprehensive explanation including:
- How components interact
- Data flow patterns
- Integration points
- Key architectural benefits
- components: Major architectural units with clear responsibilities
- patterns (optional): Document specific patterns like CFMV, CQRS, Saga
- workflow_orchestration (optional): Temporal/Cadence workflow configurations
Common Patterns:
- Monolithic application - Single deployable unit
- Microservices - Independent services with API contracts
- Service-Command Architecture - CLI-inspired command pattern
- Plugin-based - Core engine with extensible plugins
- Serverless functions - Event-driven, auto-scaling
- Temporal Workflow Orchestration - Durable workflow execution
- Feature-scoped package - Self-contained feature module
Validation Rules:
patternmust be non-empty stringdescriptionmust explain component interactions- Each component must have unique
nameand clearresponsibility - Pattern names should be descriptive (e.g., "cfmv", "saga", "cqrs")
Example:
architecture:
pattern: Service-Command Architecture
description: |
Service organized around discrete command operations following
@validkeys/contracted patterns.
components:
- name: Service Layer
responsibility: Command composition and dependency injection
- name: Command Layer
responsibility: Business logic with Result types
- name: Repository Layer
responsibility: Database access abstraction
patterns:
cfmv:
description: |
Context/Filters/Modifiers/Values for command inputs.
examples:
- example_name: listTransactions (CFM)
structure: |
{ context, filters, modifiers }---
Technology Stack Section
technology_stack:
language: string # Primary programming language
runtime: string # Runtime environment
frameworks: # List of frameworks
- string
libraries: # Organized by usage
core: # Production dependencies
- string
development: # Dev-only dependencies
- string
package_manager: string # Dependency managerField Descriptions:
- language: Primary development language (e.g., "TypeScript", "Python", "Go")
- runtime: Execution environment (e.g., "Node.js 20.x", "Python 3.11")
- frameworks: Major frameworks shaping application structure
- libraries.core: Production runtime dependencies
- libraries.development: Development-only tools (testing, linting)
- package_manager: Dependency management tool (e.g., "pnpm", "npm", "pip")
Validation Rules:
languagemust be non-emptyruntimeshould specify version when criticalpackage_managermust match language ecosystem
---
Project Structure Section
project_structure:
type: string # monorepo, multi-repo, single-repo
layout: | # ASCII directory tree
Directory structure visualization
key_directories: # Important paths
- path: string # Directory path
purpose: string # What goes hereField Descriptions:
- type: Project organization (monorepo, multi-repo, single-repo)
- layout: Visual directory tree showing folder structure
- key_directories: Important paths with purpose explanations
Layout Guidelines:
- Use ASCII tree format with clear indentation
- Include file extensions for important files
- Show 2-3 levels deep maximum
- Annotate with inline comments
---
Data Model Section
data_model:
strategy: string # Data persistence approach
database: string # Database type if applicable
schema_approach: string | | # Schema design philosophy
migrations: string | | # Migration strategy
# Optional: Database tables
tables: # Database schema details
- name: string # Table name with schema prefix
purpose: string # What data this stores
columns: | # Column definitions
Column list with types
# Optional: Database indexes
indexes: # Performance-critical indexes
index_name:
index: string # Index definition
purpose: string # Query patterns optimized
# Optional: Data retention
retention: # Compliance/legal retention
policy: string # Retention requirement
implementation:
active_period: string # Primary storage duration
active_storage: string # Where active data lives
archive_period: string # Archive duration
archive_storage: string # Where archived data lives
archival_strategy: | # Archival approach
How archiving works
deletion_policy: string # When/how data deletedField Descriptions:
- strategy: How data persists (File-based, PostgreSQL, MongoDB, In-memory)
- database: Specific database system if using one
- schema_approach: Design philosophy and patterns
- migrations: How schema changes are managed
- tables (optional): Table schema details for production systems
- indexes (optional): Performance-critical index definitions
- retention (optional): Data retention policies for regulated industries
Validation Rules:
strategymust align with technology stack- If
databasespecified, must match technology_stack.libraries - Migration strategy must be concrete
---
API Section
api:
style: string # API paradigm
framework: string # API framework
versioning: string # Version strategy
documentation: string | | # Documentation approach
# Optional: Endpoint specifications
endpoints: # Detailed endpoint list
- path: string # URL path with parameters
method: string # HTTP method
description: string # What this does
auth: string # Auth requirements
schema: string # Request/response schemaField Descriptions:
- style: API paradigm (REST, GraphQL, RPC, CLI, TRPC, gRPC)
- framework: Specific framework/library used
- versioning: How versions managed (URL path /v2/, header-based, none)
- documentation: Documentation generation approach
- endpoints (optional): Detailed REST/GraphQL endpoint specifications
Common API Styles:
- REST - Resource-oriented with HTTP methods
- GraphQL - Query language with typed schema
- TRPC - Type-safe RPC for TypeScript monorepos
- CLI - Command-line interface
- gRPC - High-performance RPC with Protocol Buffers
Validation Rules:
stylemust be recognized API paradigmframeworkshould match technology_stack.frameworksversioningmust be specified or "None" with justification
---
Security Section
security:
authentication:
method: string # Auth approach
implementation: string | | # How it works
authorization:
model: string # Authorization model
implementation: string | | # How it works
secrets:
storage: string # Where secrets live
rotation: string # Rotation policy
secrets_required: # List of secrets (optional)
- string
data_validation:
input: string # Input validation approach
output: string # Output validation approachField Descriptions:
- authentication.method: How users/services authenticate (JWT, OAuth, API keys, Session)
- authentication.implementation: Detailed auth flow
- authorization.model: Permission model (None, RBAC, ABAC, Context-based)
- authorization.implementation: How permissions checked
- secrets.storage: Where secrets kept (Env vars, AWS Secrets Manager, Vault)
- secrets.rotation: Rotation frequency
- data_validation.input: Input validation (Zod schemas, JSON Schema)
- data_validation.output: Output validation
Common Auth Methods:
- None (internal) - Trust-based for internal systems
- Session-based - Cookie sessions for web apps
- JWT - Stateless token authentication
- OAuth 2.0 / OIDC - Delegated authorization
- Multi-strategy - Multiple auth methods
Validation Rules:
- If authentication is "None", must justify
- Authorization model must be specified
- Secrets storage must be secure (not hardcoded)
---
Testing Section
testing:
strategy: string # Overall approach
types: # Test pyramid levels
unit:
framework: string
coverage_target: string
scope: string | | # Optional
integration:
framework: string
approach: string | |
coverage_target: string # Optional
e2e:
framework: string
approach: string | |
focus: string | | # Optional
mocking:
strategy: string | | # What to mock
tools: # Mocking frameworks
- stringField Descriptions:
- strategy: Testing philosophy (TDD, BDD, Integration-focused)
- types: Test pyramid levels (unit, integration, e2e)
- mocking.strategy: What gets mocked and why
- mocking.tools: Frameworks for mocking
Common Strategies:
- TDD - Test-Driven Development
- BDD - Behavior-Driven Development
- Integration-focused - Fewer unit tests, more integration
- Manual + automated - Mix of approaches
Validation Rules:
- At least one test type must be defined
- Each test type must specify framework
- Coverage targets should be realistic
---
Development & CI/CD Section
development:
workflow: string | | # Development process
code_quality:
linter: string # Linting tool
formatter: string # Code formatter
type_checker: string # Type checking tool
pre_commit_hooks: # Pre-commit checks
- string
ci_cd: # Continuous integration
platform: string # CI/CD system
pipeline: # Pipeline stages
- stage: string # Stage name
actions: # Stage actions
- stringField Descriptions:
- workflow: How developers work (local setup, branch strategy, PR process)
- code_quality: Static analysis and formatting tools
- pre_commit_hooks: Automated checks before commit
- ci_cd.platform: CI/CD system (GitHub Actions, GitLab CI, CircleCI)
- ci_cd.pipeline: Sequential stages with actions
Common Pipeline Stages:
- Validate - Lint, type check, test
- Build - Compile, bundle, package
- Deploy - Deploy to environment
- Smoke Test - Post-deployment validation
Validation Rules:
- Linter/formatter must match language ecosystem
- Pipeline must have at least one stage
- Each stage must have at least one action
---
Operations Section
operations:
deployment:
target: string # Where code runs
packaging:
format: string # Package format
distribution: string # Distribution method
environments: # Deployment environments
- name: string # Environment name
config: string | | # Configuration approach
release_process:
strategy: string # Release versioning
automation: string # Automation level
# Optional: Specialized deployment configs
specialized:
lambda: # AWS Lambda (optional)
framework: string # SAM, CDK, Serverless
configuration:
runtime: string
memory: string
timeout: string
layers: []
serverless: # Other serverless (optional)
platform: string
configuration: {}
monitoring:
logging:
format: string # Log format
destination: string # Where logs go
levels: string | | # Optional log levels
metrics:
collection: string # How metrics collected
visualization: string # Metrics dashboard
key_metrics: # Important metrics (optional)
- string
alerts:
strategy: string # When to alert
channels: # Notification channels
- string
performance:
targets: # Performance goals
response_time: string # Latency target
throughput: string # Volume target
optimization:
strategy: string | | # Optimization approach
monitoring: string # Performance tracking
scalability:
approach: string # Scaling strategy
limits: # Known limits
concurrent_users: string
data_volume: string
bottlenecks: # Potential bottlenecks
- stringField Descriptions:
Deployment:
- target: Where code runs (Kubernetes, AWS Lambda, Heroku)
- packaging: How code is packaged and distributed
- environments: Deployment targets (dev, staging, prod)
- release_process: Versioning and automation strategy
- specialized: Platform-specific configs (Lambda, serverless)
Monitoring:
- logging: Log structure and destination
- metrics: Collection and visualization
- alerts: Alert criteria and channels
Performance:
- targets: Latency and throughput goals
- optimization: Performance strategies
- monitoring: How performance tracked
Scalability:
- approach: How system scales (horizontal, vertical, auto-scaling)
- limits: Realistic system boundaries
- bottlenecks: Identified scalability constraints
Validation Rules:
- Deployment target must be concrete
- At least one environment defined
- Alert strategy must include thresholds
- Performance targets should use percentiles (P50, P95, P99)
---
Feature Flags Section
feature_flags:
strategy: string # Feature flag approach
system: string # Flag provider (Statsig, LaunchDarkly)
flags: # Feature flag definitions
- flag_id: string # Flag identifier
name: string # Full flag name (namespaced)
description: | # What flag controls
Flag purpose
default_state: boolean # Safe default
rollout_strategy: # Gradual rollout plan
phases:
- name: string
target: string
percentage: string
duration: string
cleanup_timeline: string # When to remove flag code
monitoring: # Metrics to track
- string
integration_points: # Where flag is used
- location: string
purpose: stringPurpose: Document feature flag strategy for gradual rollouts and safe deployments
When to Include:
- Production deployments requiring gradual rollout
- Risk mitigation for new features
- A/B testing or experimentation
- Kill switches for emergency disable
Field Descriptions:
- strategy: Overall flag approach (gradual rollout, A/B testing, kill switch)
- system: Feature flag provider (Statsig, LaunchDarkly, Split.io)
- flags: List of feature flags with complete specifications
Per-Flag Details:
- flag_id: Code-friendly identifier (enum key)
- name: Full namespaced flag name in provider (e.g.,
feature.product.feature_name) - description: What the flag controls (enabled/disabled behaviors)
- default_state: Safe default (usually
falsefor backward compatibility) - rollout_strategy: Phase-by-phase rollout plan with percentages
- cleanup_timeline: When to remove flag code (e.g., "30 days at 100%")
- monitoring: Metrics to track during rollout
- integration_points: Where flag is checked in codebase
Naming Convention:
Statsig: feature.{product}.{feature_name}
Enum: {feature_name} (code-friendly)Rollout Strategy Example:
rollout_strategy:
phases:
- name: Internal Testing
target: Test users
percentage: 1-2%
duration: 1-2 weeks
- name: Pilot
target: Early adopters
percentage: 10%
duration: 1 week
- name: Gradual Rollout
target: All users
percentage: 50% → 100%
duration: 2 weeks
- name: Stabilization
target: All users
percentage: 100%
duration: 30 days
- name: Cleanup
target: Remove flag code
percentage: N/A
duration: 1 weekBest Practices:
- Default to disabled - Safe backward compatibility
- Instant rollback - Disable in dashboard without deployment
- Gradual rollout - Start with 1-2%, scale to 100%
- Monitor metrics - Track performance, errors, usage during rollout
- Cleanup deadline - Remove flag code after 30 days at 100%
Integration Example:
import { checkGate } from '@spark/statsig/node'
import { FeatureGateId } from '@spark/statsig'
const isEnabled = await checkGate({
userId: userId,
featureId: FeatureGateId.feature_name
})
if (isEnabled) {
// New behavior
} else {
// Legacy behavior (backward compatible)
}Validation Rules:
- Flag names must follow provider naming conventions
- Default state should prioritize safety (backward compatible)
- Rollout strategy must include phases with clear criteria
- Cleanup timeline must be specified
- Integration points must reference actual code locations
Related Documents:
- Detailed reference:
{base_directory}/artifacts/FEATURE_FLAGS.md - ADR:
{base_directory}/adrs/ADR-00X-feature-flag-strategy.md - Rollout config:
{base_directory}/m{N}-feature-flag-configuration.md
---
Constraints Section
constraints:
technical: # Technical limitations
- string
operational: # Operational constraints
- string
architectural: # Architecture constraints (optional)
- string
business: # Business constraints (optional)
- stringField Descriptions:
- technical: Technology limits (languages, frameworks, platforms)
- operational: Process constraints (timeline, team, budget)
- architectural: Architecture mandates (patterns, standards)
- business: Business-driven constraints
Examples:
- Technical: "Must use TypeScript strict mode"
- Operational: "4-week timeline", "Team of 2 developers"
- Architectural: "Must follow service-command architecture"
- Business: "Cannot modify existing database schema"
---
Trade-offs Section
trade_offs:
- decision: string # What was decided
rationale: string # Why this choice
alternative: string # What wasn't chosen
consequence: string # Impact of decision
reversibility: string # How hard to change (optional)Field Descriptions:
- decision: Technical decision made
- rationale: Reasoning behind choice
- alternative: Options considered but not chosen
- consequence: Impact (positive and negative)
- reversibility: Ease of changing later (Low/Medium/High)
Reversibility Scale:
- Low - Core architectural decision, hard to change
- Medium - Can be changed with refactoring
- High - Easy to change, minimal impact
---
Open Questions Section
open_questions:
- question: string # Unresolved question
options: # Possible answers
- string
impact: string # What this affects
recommendation: string # Suggested resolution (optional)
decision: string # Final decision (optional)Field Descriptions:
- question: Question needing resolution
- options: Possible answers or approaches
- impact: What is affected by this decision
- recommendation: Suggested approach
- decision: Final decision if resolved
Usage:
- Use for unknowns blocking implementation
- Mark as empty array
[]when all resolved - Add
recommendationwith suggested approach - Update with
decisionwhen resolved
---
Optional: Implementation Planning Section
implementation_planning:
priorities: # Phased implementation
phase_name: # Phase identifier
- Task description
- Task description
success_criteria: # Project-level success measures
- criterion: string # Success measure
metric: string # How measured
target: string # Target value
notes: # Important implementation notes
- string
next_steps: # Immediate next actions
- stringPurpose: Optional planning section for phased projects or when implementation guidance needed
When to Include:
- Multi-phase projects with clear stage gates
- Projects with measurable KPIs
- Critical implementation warnings or guidelines
- Clear next actions for project transition
Field Descriptions:
- priorities: Phased implementation roadmap
- success_criteria: Measurable project-wide success metrics
- notes: Critical warnings, development guidelines, procedural reminders
- next_steps: Immediate actions to begin implementation
---
YAML Structural Requirements
Required Sections (13 Core)
1. Metadata (project, version, generated, business_requirements_ref) 2. Architecture 3. Technology Stack 4. Project Structure 5. Data Model 6. API 7. Security 8. Testing 9. Development & CI/CD 10. Operations (deployment, monitoring, performance, scalability) 11. Constraints 12. Trade-offs 13. Open Questions
Optional Sections
- Overview (complex projects)
- Architecture.patterns (CFMV, CQRS, Saga)
- Architecture.workflow_orchestration (Temporal/Cadence)
- Data Model subsections (tables, indexes, retention)
- Operations.deployment.specialized (Lambda, serverless)
- Feature Flags (gradual rollouts, A/B testing)
- Implementation Planning (priorities, success criteria, notes, next steps)
Multi-line Strings
Use | for multi-line strings that preserve newlines:
description: |
This is a multi-line
description with preserved
line breaks.Nested Objects
Indent consistently (2 spaces):
operations:
deployment:
target: Kubernetes
specialized:
lambda:
runtime: nodejs20.x---
Validation Rules
Cross-Document Consistency
1. Project name matches business-requirements.yaml 2. Architecture supports all functional requirements 3. Technology choices align with business constraints 4. Timeline realistic for technical scope
Technical Alignment
1. Runtime compatible with chosen language 2. Frameworks compatible with language and runtime 3. Database choice matches data model strategy 4. API style aligns with chosen frameworks 5. Testing frameworks match language ecosystem
Completeness Checks
1. All required sections present 2. No "TBD" or "TODO" in production documents 3. Trade-offs documented for major decisions 4. Open questions have options and impact analysis 5. Security addresses both authentication and authorization
---
Common Patterns by Project Type
New Service/Feature
architecture:
pattern: Service-Command Architecture
operations:
deployment:
target: Kubernetes
monitoring:
logging:
format: Structured JSONRefactoring Project
constraints:
technical:
- Must maintain backward compatibility
- No database schema changes
trade_offs:
- decision: Incremental refactoring
rationale: Minimize risk, continuous deliveryUI/Frontend Project
testing:
types:
integration:
framework: Vitest + Testing Library
e2e:
framework: Playwright
feature_flags:
system: Statsig
flags:
- flag_id: new_dashboard
default_state: falseServerless Architecture
architecture:
pattern: Serverless functions
operations:
deployment:
target: AWS Lambda
specialized:
lambda:
framework: AWS SAM
configuration:
runtime: nodejs20.x
timeout: 900 seconds---
Real-World Example References
See production examples in:
~/Sites/lumen/specifications/features/paper/plan/001-initial-buildout/requirements/technical-requirements.yaml- Temporal workflows, Lambda deployment, operations consolidated
~/Sites/lumen/specifications/features/extensions/planning/001-extension-aggregation/technical-requirements.yaml- Service-command architecture, CFMV patterns in architecture.patterns
~/Sites/lumen/specifications/features/external-transfers/planning/009-transfers-app/technical-requirements.yaml- Feature-scoped packages, feature flags with rollout strategy
---
Conversion Strategy
Primary Format: YAML (machine-readable, structured, validated) Presentation Formats: Markdown and PDF generated via CLI tools
YAML → Markdown
sherpy convert technical-requirements.yaml --to md --output technical-requirements.mdYAML → PDF
sherpy convert technical-requirements.yaml --to pdf --output technical-requirements.pdfRationale:
- YAML enforces structure and enables validation
- Markdown/PDF for stakeholder presentations
- Single source of truth (YAML) prevents drift
- CLI tools handle formatting consistently
---
Version History
2.0.0 (Current)
- Consolidated structure: 17 sections → 13 core sections (24% reduction)
- Development & CI/CD merged: CI/CD naturally under development workflow
- Operations consolidated: Deployment, monitoring, performance, scalability grouped
- Feature flags section added: Based on Statsig/LaunchDarkly patterns from production
- Workflow orchestration: Moved to architecture.workflow_orchestration
- Specialized deployments: Lambda/serverless under operations.deployment.specialized
- Implementation planning: Optional consolidated section (priorities, criteria, notes, next steps)
- Better mental model: Architecture → Tech → Dev → Ops → Constraints
1.0.0
- Initial specification
- 17 required + 9 optional sections
- Flat structure with separate sections
- Real-world validation from production projects
---
Related Documents
- business-requirements.yaml - Source business needs
- gap-analysis-worksheet.md - Pre-interview gap analysis
- milestones.yaml - Implementation plan (generated from this document)
- timeline.yaml - Delivery schedule
- qa-test-plan.yaml - Testing strategy detailed plan
- definition-of-done.yaml - Milestone acceptance criteria
- *adrs/ADR-.md** - Architecture decision records
- artifacts/FEATURE_FLAGS.md - Detailed feature flag reference