style: standardize quotes and formatting across YAML and JS files
This commit is contained in:
parent
b9968f312e
commit
5bfca9138c
|
|
@ -4,9 +4,9 @@ on:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
inputs:
|
inputs:
|
||||||
version_bump:
|
version_bump:
|
||||||
description: 'Version bump type'
|
description: "Version bump type"
|
||||||
required: true
|
required: true
|
||||||
default: 'minor'
|
default: "minor"
|
||||||
type: choice
|
type: choice
|
||||||
options:
|
options:
|
||||||
- patch
|
- patch
|
||||||
|
|
@ -30,8 +30,8 @@ jobs:
|
||||||
- name: Setup Node.js
|
- name: Setup Node.js
|
||||||
uses: actions/setup-node@v4
|
uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version: '20'
|
node-version: "20"
|
||||||
registry-url: 'https://registry.npmjs.org'
|
registry-url: "https://registry.npmjs.org"
|
||||||
|
|
||||||
- name: Configure Git
|
- name: Configure Git
|
||||||
run: |
|
run: |
|
||||||
|
|
|
||||||
|
|
@ -25,10 +25,10 @@ Comprehensive guide for determining appropriate test levels (unit, integration,
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
unit_test:
|
unit_test:
|
||||||
component: "PriceCalculator"
|
component: 'PriceCalculator'
|
||||||
scenario: "Calculate discount with multiple rules"
|
scenario: 'Calculate discount with multiple rules'
|
||||||
justification: "Complex business logic with multiple branches"
|
justification: 'Complex business logic with multiple branches'
|
||||||
mock_requirements: "None - pure function"
|
mock_requirements: 'None - pure function'
|
||||||
```
|
```
|
||||||
|
|
||||||
### Integration Tests
|
### Integration Tests
|
||||||
|
|
@ -52,10 +52,10 @@ unit_test:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
integration_test:
|
integration_test:
|
||||||
components: ["UserService", "AuthRepository"]
|
components: ['UserService', 'AuthRepository']
|
||||||
scenario: "Create user with role assignment"
|
scenario: 'Create user with role assignment'
|
||||||
justification: "Critical data flow between service and persistence"
|
justification: 'Critical data flow between service and persistence'
|
||||||
test_environment: "In-memory database"
|
test_environment: 'In-memory database'
|
||||||
```
|
```
|
||||||
|
|
||||||
### End-to-End Tests
|
### End-to-End Tests
|
||||||
|
|
@ -79,10 +79,10 @@ integration_test:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
e2e_test:
|
e2e_test:
|
||||||
journey: "Complete checkout process"
|
journey: 'Complete checkout process'
|
||||||
scenario: "User purchases with saved payment method"
|
scenario: 'User purchases with saved payment method'
|
||||||
justification: "Revenue-critical path requiring full validation"
|
justification: 'Revenue-critical path requiring full validation'
|
||||||
environment: "Staging with test payment gateway"
|
environment: 'Staging with test payment gateway'
|
||||||
```
|
```
|
||||||
|
|
||||||
## Test Level Selection Rules
|
## Test Level Selection Rules
|
||||||
|
|
|
||||||
|
|
@ -6,18 +6,19 @@ Quick NFR validation focused on the core four: security, performance, reliabilit
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
required:
|
required:
|
||||||
- story_id: "{epic}.{story}" # e.g., "1.3"
|
- story_id: '{epic}.{story}' # e.g., "1.3"
|
||||||
- story_path: "docs/stories/{epic}.{story}.*.md"
|
- story_path: 'docs/stories/{epic}.{story}.*.md'
|
||||||
|
|
||||||
optional:
|
optional:
|
||||||
- architecture_refs: "docs/architecture/*.md"
|
- architecture_refs: 'docs/architecture/*.md'
|
||||||
- technical_preferences: "docs/technical-preferences.md"
|
- technical_preferences: 'docs/technical-preferences.md'
|
||||||
- acceptance_criteria: From story file
|
- acceptance_criteria: From story file
|
||||||
```
|
```
|
||||||
|
|
||||||
## Purpose
|
## Purpose
|
||||||
|
|
||||||
Assess non-functional requirements for a story and generate:
|
Assess non-functional requirements for a story and generate:
|
||||||
|
|
||||||
1. YAML block for the gate file's `nfr_validation` section
|
1. YAML block for the gate file's `nfr_validation` section
|
||||||
2. Brief markdown assessment saved to `docs/qa/assessments/{epic}.{story}-nfr-{YYYYMMDD}.md`
|
2. Brief markdown assessment saved to `docs/qa/assessments/{epic}.{story}-nfr-{YYYYMMDD}.md`
|
||||||
|
|
||||||
|
|
@ -26,6 +27,7 @@ Assess non-functional requirements for a story and generate:
|
||||||
### 0. Fail-safe for Missing Inputs
|
### 0. Fail-safe for Missing Inputs
|
||||||
|
|
||||||
If story_path or story file can't be found:
|
If story_path or story file can't be found:
|
||||||
|
|
||||||
- Still create assessment file with note: "Source story not found"
|
- Still create assessment file with note: "Source story not found"
|
||||||
- Set all selected NFRs to CONCERNS with notes: "Target unknown / evidence missing"
|
- Set all selected NFRs to CONCERNS with notes: "Target unknown / evidence missing"
|
||||||
- Continue with assessment to provide value
|
- Continue with assessment to provide value
|
||||||
|
|
@ -52,6 +54,7 @@ Which NFRs should I assess? (Enter numbers or press Enter for default)
|
||||||
### 2. Check for Thresholds
|
### 2. Check for Thresholds
|
||||||
|
|
||||||
Look for NFR requirements in:
|
Look for NFR requirements in:
|
||||||
|
|
||||||
- Story acceptance criteria
|
- Story acceptance criteria
|
||||||
- `docs/architecture/*.md` files
|
- `docs/architecture/*.md` files
|
||||||
- `docs/technical-preferences.md`
|
- `docs/technical-preferences.md`
|
||||||
|
|
@ -72,6 +75,7 @@ No security requirements found. Required auth method?
|
||||||
### 3. Quick Assessment
|
### 3. Quick Assessment
|
||||||
|
|
||||||
For each selected NFR, check:
|
For each selected NFR, check:
|
||||||
|
|
||||||
- Is there evidence it's implemented?
|
- Is there evidence it's implemented?
|
||||||
- Can we validate it?
|
- Can we validate it?
|
||||||
- Are there obvious gaps?
|
- Are there obvious gaps?
|
||||||
|
|
@ -88,16 +92,16 @@ nfr_validation:
|
||||||
_assessed: [security, performance, reliability, maintainability]
|
_assessed: [security, performance, reliability, maintainability]
|
||||||
security:
|
security:
|
||||||
status: CONCERNS
|
status: CONCERNS
|
||||||
notes: "No rate limiting on auth endpoints"
|
notes: 'No rate limiting on auth endpoints'
|
||||||
performance:
|
performance:
|
||||||
status: PASS
|
status: PASS
|
||||||
notes: "Response times < 200ms verified"
|
notes: 'Response times < 200ms verified'
|
||||||
reliability:
|
reliability:
|
||||||
status: PASS
|
status: PASS
|
||||||
notes: "Error handling and retries implemented"
|
notes: 'Error handling and retries implemented'
|
||||||
maintainability:
|
maintainability:
|
||||||
status: CONCERNS
|
status: CONCERNS
|
||||||
notes: "Test coverage at 65%, target is 80%"
|
notes: 'Test coverage at 65%, target is 80%'
|
||||||
```
|
```
|
||||||
|
|
||||||
## Deterministic Status Rules
|
## Deterministic Status Rules
|
||||||
|
|
@ -123,18 +127,21 @@ If `technical-preferences.md` defines custom weights, use those instead.
|
||||||
|
|
||||||
```markdown
|
```markdown
|
||||||
# NFR Assessment: {epic}.{story}
|
# NFR Assessment: {epic}.{story}
|
||||||
|
|
||||||
Date: {date}
|
Date: {date}
|
||||||
Reviewer: Quinn
|
Reviewer: Quinn
|
||||||
|
|
||||||
<!-- Note: Source story not found (if applicable) -->
|
<!-- Note: Source story not found (if applicable) -->
|
||||||
|
|
||||||
## Summary
|
## Summary
|
||||||
|
|
||||||
- Security: CONCERNS - Missing rate limiting
|
- Security: CONCERNS - Missing rate limiting
|
||||||
- Performance: PASS - Meets <200ms requirement
|
- Performance: PASS - Meets <200ms requirement
|
||||||
- Reliability: PASS - Proper error handling
|
- Reliability: PASS - Proper error handling
|
||||||
- Maintainability: CONCERNS - Test coverage below target
|
- Maintainability: CONCERNS - Test coverage below target
|
||||||
|
|
||||||
## Critical Issues
|
## Critical Issues
|
||||||
|
|
||||||
1. **No rate limiting** (Security)
|
1. **No rate limiting** (Security)
|
||||||
- Risk: Brute force attacks possible
|
- Risk: Brute force attacks possible
|
||||||
- Fix: Add rate limiting middleware to auth endpoints
|
- Fix: Add rate limiting middleware to auth endpoints
|
||||||
|
|
@ -144,6 +151,7 @@ Reviewer: Quinn
|
||||||
- Fix: Add tests for uncovered branches
|
- Fix: Add tests for uncovered branches
|
||||||
|
|
||||||
## Quick Wins
|
## Quick Wins
|
||||||
|
|
||||||
- Add rate limiting: ~2 hours
|
- Add rate limiting: ~2 hours
|
||||||
- Increase test coverage: ~4 hours
|
- Increase test coverage: ~4 hours
|
||||||
- Add performance monitoring: ~1 hour
|
- Add performance monitoring: ~1 hour
|
||||||
|
|
@ -152,6 +160,7 @@ Reviewer: Quinn
|
||||||
## Output 3: Story Update Line
|
## Output 3: Story Update Line
|
||||||
|
|
||||||
**End with this line for the review task to quote:**
|
**End with this line for the review task to quote:**
|
||||||
|
|
||||||
```
|
```
|
||||||
NFR assessment: docs/qa/assessments/{epic}.{story}-nfr-{YYYYMMDD}.md
|
NFR assessment: docs/qa/assessments/{epic}.{story}-nfr-{YYYYMMDD}.md
|
||||||
```
|
```
|
||||||
|
|
@ -159,6 +168,7 @@ NFR assessment: docs/qa/assessments/{epic}.{story}-nfr-{YYYYMMDD}.md
|
||||||
## Output 4: Gate Integration Line
|
## Output 4: Gate Integration Line
|
||||||
|
|
||||||
**Always print at the end:**
|
**Always print at the end:**
|
||||||
|
|
||||||
```
|
```
|
||||||
Gate NFR block ready → paste into docs/qa/gates/{epic}.{story}-{slug}.yml under nfr_validation
|
Gate NFR block ready → paste into docs/qa/gates/{epic}.{story}-{slug}.yml under nfr_validation
|
||||||
```
|
```
|
||||||
|
|
@ -166,66 +176,82 @@ Gate NFR block ready → paste into docs/qa/gates/{epic}.{story}-{slug}.yml unde
|
||||||
## Assessment Criteria
|
## Assessment Criteria
|
||||||
|
|
||||||
### Security
|
### Security
|
||||||
|
|
||||||
**PASS if:**
|
**PASS if:**
|
||||||
|
|
||||||
- Authentication implemented
|
- Authentication implemented
|
||||||
- Authorization enforced
|
- Authorization enforced
|
||||||
- Input validation present
|
- Input validation present
|
||||||
- No hardcoded secrets
|
- No hardcoded secrets
|
||||||
|
|
||||||
**CONCERNS if:**
|
**CONCERNS if:**
|
||||||
|
|
||||||
- Missing rate limiting
|
- Missing rate limiting
|
||||||
- Weak encryption
|
- Weak encryption
|
||||||
- Incomplete authorization
|
- Incomplete authorization
|
||||||
|
|
||||||
**FAIL if:**
|
**FAIL if:**
|
||||||
|
|
||||||
- No authentication
|
- No authentication
|
||||||
- Hardcoded credentials
|
- Hardcoded credentials
|
||||||
- SQL injection vulnerabilities
|
- SQL injection vulnerabilities
|
||||||
|
|
||||||
### Performance
|
### Performance
|
||||||
|
|
||||||
**PASS if:**
|
**PASS if:**
|
||||||
|
|
||||||
- Meets response time targets
|
- Meets response time targets
|
||||||
- No obvious bottlenecks
|
- No obvious bottlenecks
|
||||||
- Reasonable resource usage
|
- Reasonable resource usage
|
||||||
|
|
||||||
**CONCERNS if:**
|
**CONCERNS if:**
|
||||||
|
|
||||||
- Close to limits
|
- Close to limits
|
||||||
- Missing indexes
|
- Missing indexes
|
||||||
- No caching strategy
|
- No caching strategy
|
||||||
|
|
||||||
**FAIL if:**
|
**FAIL if:**
|
||||||
|
|
||||||
- Exceeds response time limits
|
- Exceeds response time limits
|
||||||
- Memory leaks
|
- Memory leaks
|
||||||
- Unoptimized queries
|
- Unoptimized queries
|
||||||
|
|
||||||
### Reliability
|
### Reliability
|
||||||
|
|
||||||
**PASS if:**
|
**PASS if:**
|
||||||
|
|
||||||
- Error handling present
|
- Error handling present
|
||||||
- Graceful degradation
|
- Graceful degradation
|
||||||
- Retry logic where needed
|
- Retry logic where needed
|
||||||
|
|
||||||
**CONCERNS if:**
|
**CONCERNS if:**
|
||||||
|
|
||||||
- Some error cases unhandled
|
- Some error cases unhandled
|
||||||
- No circuit breakers
|
- No circuit breakers
|
||||||
- Missing health checks
|
- Missing health checks
|
||||||
|
|
||||||
**FAIL if:**
|
**FAIL if:**
|
||||||
|
|
||||||
- No error handling
|
- No error handling
|
||||||
- Crashes on errors
|
- Crashes on errors
|
||||||
- No recovery mechanisms
|
- No recovery mechanisms
|
||||||
|
|
||||||
### Maintainability
|
### Maintainability
|
||||||
|
|
||||||
**PASS if:**
|
**PASS if:**
|
||||||
|
|
||||||
- Test coverage meets target
|
- Test coverage meets target
|
||||||
- Code well-structured
|
- Code well-structured
|
||||||
- Documentation present
|
- Documentation present
|
||||||
|
|
||||||
**CONCERNS if:**
|
**CONCERNS if:**
|
||||||
|
|
||||||
- Test coverage below target
|
- Test coverage below target
|
||||||
- Some code duplication
|
- Some code duplication
|
||||||
- Missing documentation
|
- Missing documentation
|
||||||
|
|
||||||
**FAIL if:**
|
**FAIL if:**
|
||||||
|
|
||||||
- No tests
|
- No tests
|
||||||
- Highly coupled code
|
- Highly coupled code
|
||||||
- No documentation
|
- No documentation
|
||||||
|
|
@ -291,6 +317,7 @@ maintainability:
|
||||||
8. **Portability**: Adaptability, installability
|
8. **Portability**: Adaptability, installability
|
||||||
|
|
||||||
Use these when assessing beyond the core four.
|
Use these when assessing beyond the core four.
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
|
|
@ -304,12 +331,13 @@ performance_deep_dive:
|
||||||
p99: 350ms
|
p99: 350ms
|
||||||
database:
|
database:
|
||||||
slow_queries: 2
|
slow_queries: 2
|
||||||
missing_indexes: ["users.email", "orders.user_id"]
|
missing_indexes: ['users.email', 'orders.user_id']
|
||||||
caching:
|
caching:
|
||||||
hit_rate: 0%
|
hit_rate: 0%
|
||||||
recommendation: "Add Redis for session data"
|
recommendation: 'Add Redis for session data'
|
||||||
load_test:
|
load_test:
|
||||||
max_rps: 150
|
max_rps: 150
|
||||||
breaking_point: 200 rps
|
breaking_point: 200 rps
|
||||||
```
|
```
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|
@ -27,11 +27,11 @@ Slug rules:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
schema: 1
|
schema: 1
|
||||||
story: "{epic}.{story}"
|
story: '{epic}.{story}'
|
||||||
gate: PASS|CONCERNS|FAIL|WAIVED
|
gate: PASS|CONCERNS|FAIL|WAIVED
|
||||||
status_reason: "1-2 sentence explanation of gate decision"
|
status_reason: '1-2 sentence explanation of gate decision'
|
||||||
reviewer: "Quinn"
|
reviewer: 'Quinn'
|
||||||
updated: "{ISO-8601 timestamp}"
|
updated: '{ISO-8601 timestamp}'
|
||||||
top_issues: [] # Empty array if no issues
|
top_issues: [] # Empty array if no issues
|
||||||
waiver: { active: false } # Only set active: true if WAIVED
|
waiver: { active: false } # Only set active: true if WAIVED
|
||||||
```
|
```
|
||||||
|
|
@ -40,20 +40,20 @@ waiver: { active: false } # Only set active: true if WAIVED
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
schema: 1
|
schema: 1
|
||||||
story: "1.3"
|
story: '1.3'
|
||||||
gate: CONCERNS
|
gate: CONCERNS
|
||||||
status_reason: "Missing rate limiting on auth endpoints poses security risk."
|
status_reason: 'Missing rate limiting on auth endpoints poses security risk.'
|
||||||
reviewer: "Quinn"
|
reviewer: 'Quinn'
|
||||||
updated: "2025-01-12T10:15:00Z"
|
updated: '2025-01-12T10:15:00Z'
|
||||||
top_issues:
|
top_issues:
|
||||||
- id: "SEC-001"
|
- id: 'SEC-001'
|
||||||
severity: high # ONLY: low|medium|high
|
severity: high # ONLY: low|medium|high
|
||||||
finding: "No rate limiting on login endpoint"
|
finding: 'No rate limiting on login endpoint'
|
||||||
suggested_action: "Add rate limiting middleware before production"
|
suggested_action: 'Add rate limiting middleware before production'
|
||||||
- id: "TEST-001"
|
- id: 'TEST-001'
|
||||||
severity: medium
|
severity: medium
|
||||||
finding: "No integration tests for auth flow"
|
finding: 'No integration tests for auth flow'
|
||||||
suggested_action: "Add integration test coverage"
|
suggested_action: 'Add integration test coverage'
|
||||||
waiver: { active: false }
|
waiver: { active: false }
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
@ -61,20 +61,20 @@ waiver: { active: false }
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
schema: 1
|
schema: 1
|
||||||
story: "1.3"
|
story: '1.3'
|
||||||
gate: WAIVED
|
gate: WAIVED
|
||||||
status_reason: "Known issues accepted for MVP release."
|
status_reason: 'Known issues accepted for MVP release.'
|
||||||
reviewer: "Quinn"
|
reviewer: 'Quinn'
|
||||||
updated: "2025-01-12T10:15:00Z"
|
updated: '2025-01-12T10:15:00Z'
|
||||||
top_issues:
|
top_issues:
|
||||||
- id: "PERF-001"
|
- id: 'PERF-001'
|
||||||
severity: low
|
severity: low
|
||||||
finding: "Dashboard loads slowly with 1000+ items"
|
finding: 'Dashboard loads slowly with 1000+ items'
|
||||||
suggested_action: "Implement pagination in next sprint"
|
suggested_action: 'Implement pagination in next sprint'
|
||||||
waiver:
|
waiver:
|
||||||
active: true
|
active: true
|
||||||
reason: "MVP release - performance optimization deferred"
|
reason: 'MVP release - performance optimization deferred'
|
||||||
approved_by: "Product Owner"
|
approved_by: 'Product Owner'
|
||||||
```
|
```
|
||||||
|
|
||||||
## Gate Decision Criteria
|
## Gate Decision Criteria
|
||||||
|
|
|
||||||
|
|
@ -6,10 +6,10 @@ Generate a comprehensive risk assessment matrix for a story implementation using
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
required:
|
required:
|
||||||
- story_id: "{epic}.{story}" # e.g., "1.3"
|
- story_id: '{epic}.{story}' # e.g., "1.3"
|
||||||
- story_path: "docs/stories/{epic}.{story}.*.md"
|
- story_path: 'docs/stories/{epic}.{story}.*.md'
|
||||||
- story_title: "{title}" # If missing, derive from story file H1
|
- story_title: '{title}' # If missing, derive from story file H1
|
||||||
- story_slug: "{slug}" # If missing, derive from title (lowercase, hyphenated)
|
- story_slug: '{slug}' # If missing, derive from title (lowercase, hyphenated)
|
||||||
```
|
```
|
||||||
|
|
||||||
## Purpose
|
## Purpose
|
||||||
|
|
@ -79,14 +79,14 @@ For each category, identify specific risks:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
risk:
|
risk:
|
||||||
id: "SEC-001" # Use prefixes: SEC, PERF, DATA, BUS, OPS, TECH
|
id: 'SEC-001' # Use prefixes: SEC, PERF, DATA, BUS, OPS, TECH
|
||||||
category: security
|
category: security
|
||||||
title: "Insufficient input validation on user forms"
|
title: 'Insufficient input validation on user forms'
|
||||||
description: "Form inputs not properly sanitized could lead to XSS attacks"
|
description: 'Form inputs not properly sanitized could lead to XSS attacks'
|
||||||
affected_components:
|
affected_components:
|
||||||
- "UserRegistrationForm"
|
- 'UserRegistrationForm'
|
||||||
- "ProfileUpdateForm"
|
- 'ProfileUpdateForm'
|
||||||
detection_method: "Code review revealed missing validation"
|
detection_method: 'Code review revealed missing validation'
|
||||||
```
|
```
|
||||||
|
|
||||||
### 2. Risk Assessment
|
### 2. Risk Assessment
|
||||||
|
|
@ -133,20 +133,20 @@ For each identified risk, provide mitigation:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
mitigation:
|
mitigation:
|
||||||
risk_id: "SEC-001"
|
risk_id: 'SEC-001'
|
||||||
strategy: "preventive" # preventive|detective|corrective
|
strategy: 'preventive' # preventive|detective|corrective
|
||||||
actions:
|
actions:
|
||||||
- "Implement input validation library (e.g., validator.js)"
|
- 'Implement input validation library (e.g., validator.js)'
|
||||||
- "Add CSP headers to prevent XSS execution"
|
- 'Add CSP headers to prevent XSS execution'
|
||||||
- "Sanitize all user inputs before storage"
|
- 'Sanitize all user inputs before storage'
|
||||||
- "Escape all outputs in templates"
|
- 'Escape all outputs in templates'
|
||||||
testing_requirements:
|
testing_requirements:
|
||||||
- "Security testing with OWASP ZAP"
|
- 'Security testing with OWASP ZAP'
|
||||||
- "Manual penetration testing of forms"
|
- 'Manual penetration testing of forms'
|
||||||
- "Unit tests for validation functions"
|
- 'Unit tests for validation functions'
|
||||||
residual_risk: "Low - Some zero-day vulnerabilities may remain"
|
residual_risk: 'Low - Some zero-day vulnerabilities may remain'
|
||||||
owner: "dev"
|
owner: 'dev'
|
||||||
timeline: "Before deployment"
|
timeline: 'Before deployment'
|
||||||
```
|
```
|
||||||
|
|
||||||
## Outputs
|
## Outputs
|
||||||
|
|
@ -172,12 +172,12 @@ risk_summary:
|
||||||
highest:
|
highest:
|
||||||
id: SEC-001
|
id: SEC-001
|
||||||
score: 9
|
score: 9
|
||||||
title: "XSS on profile form"
|
title: 'XSS on profile form'
|
||||||
recommendations:
|
recommendations:
|
||||||
must_fix:
|
must_fix:
|
||||||
- "Add input sanitization & CSP"
|
- 'Add input sanitization & CSP'
|
||||||
monitor:
|
monitor:
|
||||||
- "Add security alerts for auth endpoints"
|
- 'Add security alerts for auth endpoints'
|
||||||
```
|
```
|
||||||
|
|
||||||
### Output 2: Markdown Report
|
### Output 2: Markdown Report
|
||||||
|
|
|
||||||
|
|
@ -6,10 +6,10 @@ Create comprehensive test scenarios with appropriate test level recommendations
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
required:
|
required:
|
||||||
- story_id: "{epic}.{story}" # e.g., "1.3"
|
- story_id: '{epic}.{story}' # e.g., "1.3"
|
||||||
- story_path: "{devStoryLocation}/{epic}.{story}.*.md" # Path from core-config.yaml
|
- story_path: '{devStoryLocation}/{epic}.{story}.*.md' # Path from core-config.yaml
|
||||||
- story_title: "{title}" # If missing, derive from story file H1
|
- story_title: '{title}' # If missing, derive from story file H1
|
||||||
- story_slug: "{slug}" # If missing, derive from title (lowercase, hyphenated)
|
- story_slug: '{slug}' # If missing, derive from title (lowercase, hyphenated)
|
||||||
```
|
```
|
||||||
|
|
||||||
## Purpose
|
## Purpose
|
||||||
|
|
@ -62,13 +62,13 @@ For each identified test need, create:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
test_scenario:
|
test_scenario:
|
||||||
id: "{epic}.{story}-{LEVEL}-{SEQ}"
|
id: '{epic}.{story}-{LEVEL}-{SEQ}'
|
||||||
requirement: "AC reference"
|
requirement: 'AC reference'
|
||||||
priority: P0|P1|P2|P3
|
priority: P0|P1|P2|P3
|
||||||
level: unit|integration|e2e
|
level: unit|integration|e2e
|
||||||
description: "What is being tested"
|
description: 'What is being tested'
|
||||||
justification: "Why this level was chosen"
|
justification: 'Why this level was chosen'
|
||||||
mitigates_risks: ["RISK-001"] # If risk profile exists
|
mitigates_risks: ['RISK-001'] # If risk profile exists
|
||||||
```
|
```
|
||||||
|
|
||||||
### 5. Validate Coverage
|
### 5. Validate Coverage
|
||||||
|
|
|
||||||
|
|
@ -31,21 +31,21 @@ Identify all testable requirements from:
|
||||||
For each requirement, document which tests validate it. Use Given-When-Then to describe what the test validates (not how it's written):
|
For each requirement, document which tests validate it. Use Given-When-Then to describe what the test validates (not how it's written):
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
requirement: "AC1: User can login with valid credentials"
|
requirement: 'AC1: User can login with valid credentials'
|
||||||
test_mappings:
|
test_mappings:
|
||||||
- test_file: "auth/login.test.ts"
|
- test_file: 'auth/login.test.ts'
|
||||||
test_case: "should successfully login with valid email and password"
|
test_case: 'should successfully login with valid email and password'
|
||||||
# Given-When-Then describes WHAT the test validates, not HOW it's coded
|
# Given-When-Then describes WHAT the test validates, not HOW it's coded
|
||||||
given: "A registered user with valid credentials"
|
given: 'A registered user with valid credentials'
|
||||||
when: "They submit the login form"
|
when: 'They submit the login form'
|
||||||
then: "They are redirected to dashboard and session is created"
|
then: 'They are redirected to dashboard and session is created'
|
||||||
coverage: full
|
coverage: full
|
||||||
|
|
||||||
- test_file: "e2e/auth-flow.test.ts"
|
- test_file: 'e2e/auth-flow.test.ts'
|
||||||
test_case: "complete login flow"
|
test_case: 'complete login flow'
|
||||||
given: "User on login page"
|
given: 'User on login page'
|
||||||
when: "Entering valid credentials and submitting"
|
when: 'Entering valid credentials and submitting'
|
||||||
then: "Dashboard loads with user data"
|
then: 'Dashboard loads with user data'
|
||||||
coverage: integration
|
coverage: integration
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
@ -67,19 +67,19 @@ Document any gaps found:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
coverage_gaps:
|
coverage_gaps:
|
||||||
- requirement: "AC3: Password reset email sent within 60 seconds"
|
- requirement: 'AC3: Password reset email sent within 60 seconds'
|
||||||
gap: "No test for email delivery timing"
|
gap: 'No test for email delivery timing'
|
||||||
severity: medium
|
severity: medium
|
||||||
suggested_test:
|
suggested_test:
|
||||||
type: integration
|
type: integration
|
||||||
description: "Test email service SLA compliance"
|
description: 'Test email service SLA compliance'
|
||||||
|
|
||||||
- requirement: "AC5: Support 1000 concurrent users"
|
- requirement: 'AC5: Support 1000 concurrent users'
|
||||||
gap: "No load testing implemented"
|
gap: 'No load testing implemented'
|
||||||
severity: high
|
severity: high
|
||||||
suggested_test:
|
suggested_test:
|
||||||
type: performance
|
type: performance
|
||||||
description: "Load test with 1000 concurrent connections"
|
description: 'Load test with 1000 concurrent connections'
|
||||||
```
|
```
|
||||||
|
|
||||||
## Outputs
|
## Outputs
|
||||||
|
|
@ -95,11 +95,11 @@ trace:
|
||||||
full: Y
|
full: Y
|
||||||
partial: Z
|
partial: Z
|
||||||
none: W
|
none: W
|
||||||
planning_ref: "docs/qa/assessments/{epic}.{story}-test-design-{YYYYMMDD}.md"
|
planning_ref: 'docs/qa/assessments/{epic}.{story}-test-design-{YYYYMMDD}.md'
|
||||||
uncovered:
|
uncovered:
|
||||||
- ac: "AC3"
|
- ac: 'AC3'
|
||||||
reason: "No test found for password reset timing"
|
reason: 'No test found for password reset timing'
|
||||||
notes: "See docs/qa/assessments/{epic}.{story}-trace-{YYYYMMDD}.md"
|
notes: 'See docs/qa/assessments/{epic}.{story}-trace-{YYYYMMDD}.md'
|
||||||
```
|
```
|
||||||
|
|
||||||
### Output 2: Traceability Report
|
### Output 2: Traceability Report
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ The Test Architect (Quinn) provides comprehensive quality assurance throughout t
|
||||||
### Quick Command Reference
|
### Quick Command Reference
|
||||||
|
|
||||||
| **Stage** | **Command** | **Purpose** | **Output** | **Priority** |
|
| **Stage** | **Command** | **Purpose** | **Output** | **Priority** |
|
||||||
|-----------|------------|-------------|------------|--------------|
|
| ------------------------ | ----------- | --------------------------------------- | --------------------------------------------------------------- | --------------------------- |
|
||||||
| **After Story Approval** | `*risk` | Identify integration & regression risks | `docs/qa/assessments/{epic}.{story}-risk-{YYYYMMDD}.md` | High for complex/brownfield |
|
| **After Story Approval** | `*risk` | Identify integration & regression risks | `docs/qa/assessments/{epic}.{story}-risk-{YYYYMMDD}.md` | High for complex/brownfield |
|
||||||
| | `*design` | Create test strategy for dev | `docs/qa/assessments/{epic}.{story}-test-design-{YYYYMMDD}.md` | High for new features |
|
| | `*design` | Create test strategy for dev | `docs/qa/assessments/{epic}.{story}-test-design-{YYYYMMDD}.md` | High for new features |
|
||||||
| **During Development** | `*trace` | Verify test coverage | `docs/qa/assessments/{epic}.{story}-trace-{YYYYMMDD}.md` | Medium |
|
| **During Development** | `*trace` | Verify test coverage | `docs/qa/assessments/{epic}.{story}-trace-{YYYYMMDD}.md` | Medium |
|
||||||
|
|
@ -135,7 +135,7 @@ The Test Architect (Quinn) provides comprehensive quality assurance throughout t
|
||||||
### Understanding Gate Decisions
|
### Understanding Gate Decisions
|
||||||
|
|
||||||
| **Status** | **Meaning** | **Action Required** | **Can Proceed?** |
|
| **Status** | **Meaning** | **Action Required** | **Can Proceed?** |
|
||||||
|------------|-------------|-------------------|------------------|
|
| ------------ | -------------------------------------------- | ----------------------- | ---------------- |
|
||||||
| **PASS** | All critical requirements met | None | ✅ Yes |
|
| **PASS** | All critical requirements met | None | ✅ Yes |
|
||||||
| **CONCERNS** | Non-critical issues found | Team review recommended | ⚠️ With caution |
|
| **CONCERNS** | Non-critical issues found | Team review recommended | ⚠️ With caution |
|
||||||
| **FAIL** | Critical issues (security, missing P0 tests) | Must fix | ❌ No |
|
| **FAIL** | Critical issues (security, missing P0 tests) | Must fix | ❌ No |
|
||||||
|
|
@ -146,7 +146,7 @@ The Test Architect (Quinn) provides comprehensive quality assurance throughout t
|
||||||
The Test Architect uses risk scoring to prioritize testing:
|
The Test Architect uses risk scoring to prioritize testing:
|
||||||
|
|
||||||
| **Risk Score** | **Calculation** | **Testing Priority** | **Gate Impact** |
|
| **Risk Score** | **Calculation** | **Testing Priority** | **Gate Impact** |
|
||||||
|---------------|----------------|-------------------|----------------|
|
| -------------- | ------------------------------ | ------------------------- | ------------------------ |
|
||||||
| **9** | High probability × High impact | P0 - Must test thoroughly | FAIL if untested |
|
| **9** | High probability × High impact | P0 - Must test thoroughly | FAIL if untested |
|
||||||
| **6** | Medium-high combinations | P1 - Should test well | CONCERNS if gaps |
|
| **6** | Medium-high combinations | P1 - Should test well | CONCERNS if gaps |
|
||||||
| **4** | Medium combinations | P1 - Should test | CONCERNS if notable gaps |
|
| **4** | Medium combinations | P1 - Should test | CONCERNS if notable gaps |
|
||||||
|
|
@ -228,7 +228,7 @@ All Test Architect activities create permanent records:
|
||||||
**Should I run Test Architect commands?**
|
**Should I run Test Architect commands?**
|
||||||
|
|
||||||
| **Scenario** | **Before Dev** | **During Dev** | **After Dev** |
|
| **Scenario** | **Before Dev** | **During Dev** | **After Dev** |
|
||||||
|-------------|---------------|----------------|---------------|
|
| ------------------------ | ------------------------------- | ---------------------------- | ---------------------------- |
|
||||||
| **Simple bug fix** | Optional | Optional | Required `*review` |
|
| **Simple bug fix** | Optional | Optional | Required `*review` |
|
||||||
| **New feature** | Recommended `*risk`, `*design` | Optional `*trace` | Required `*review` |
|
| **New feature** | Recommended `*risk`, `*design` | Optional `*trace` | Required `*review` |
|
||||||
| **Brownfield change** | **Required** `*risk`, `*design` | Recommended `*trace`, `*nfr` | Required `*review` |
|
| **Brownfield change** | **Required** `*risk`, `*design` | Recommended `*trace`, `*nfr` | Required `*review` |
|
||||||
|
|
|
||||||
|
|
@ -377,7 +377,7 @@ Manages quality gate decisions:
|
||||||
The Test Architect provides value throughout the entire development lifecycle. Here's when and how to leverage each capability:
|
The Test Architect provides value throughout the entire development lifecycle. Here's when and how to leverage each capability:
|
||||||
|
|
||||||
| **Stage** | **Command** | **When to Use** | **Value** | **Output** |
|
| **Stage** | **Command** | **When to Use** | **Value** | **Output** |
|
||||||
|-----------|------------|-----------------|-----------|------------|
|
| ------------------ | ----------- | ----------------------- | -------------------------- | -------------------------------------------------------------- |
|
||||||
| **Story Drafting** | `*risk` | After SM drafts story | Identify pitfalls early | `docs/qa/assessments/{epic}.{story}-risk-{YYYYMMDD}.md` |
|
| **Story Drafting** | `*risk` | After SM drafts story | Identify pitfalls early | `docs/qa/assessments/{epic}.{story}-risk-{YYYYMMDD}.md` |
|
||||||
| | `*design` | After risk assessment | Guide dev on test strategy | `docs/qa/assessments/{epic}.{story}-test-design-{YYYYMMDD}.md` |
|
| | `*design` | After risk assessment | Guide dev on test strategy | `docs/qa/assessments/{epic}.{story}-test-design-{YYYYMMDD}.md` |
|
||||||
| **Development** | `*trace` | Mid-implementation | Verify test coverage | `docs/qa/assessments/{epic}.{story}-trace-{YYYYMMDD}.md` |
|
| **Development** | `*trace` | Mid-implementation | Verify test coverage | `docs/qa/assessments/{epic}.{story}-trace-{YYYYMMDD}.md` |
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ const yaml = require('js-yaml');
|
||||||
const chalk = require('chalk').default || require('chalk');
|
const chalk = require('chalk').default || require('chalk');
|
||||||
const inquirer = require('inquirer').default || require('inquirer');
|
const inquirer = require('inquirer').default || require('inquirer');
|
||||||
const semver = require('semver');
|
const semver = require('semver');
|
||||||
const https = require('https');
|
const https = require('node:https');
|
||||||
|
|
||||||
// Handle both execution contexts (from root via npx or from installer directory)
|
// Handle both execution contexts (from root via npx or from installer directory)
|
||||||
let version;
|
let version;
|
||||||
|
|
@ -106,7 +106,7 @@ program
|
||||||
console.log('Checking for updates...');
|
console.log('Checking for updates...');
|
||||||
|
|
||||||
// Make HTTP request to npm registry for latest version info
|
// Make HTTP request to npm registry for latest version info
|
||||||
const req = https.get(`https://registry.npmjs.org/${packageName}/latest`, res => {
|
const req = https.get(`https://registry.npmjs.org/${packageName}/latest`, (res) => {
|
||||||
// Check for HTTP errors (non-200 status codes)
|
// Check for HTTP errors (non-200 status codes)
|
||||||
if (res.statusCode !== 200) {
|
if (res.statusCode !== 200) {
|
||||||
console.error(chalk.red(`Update check failed: Received status code ${res.statusCode}`));
|
console.error(chalk.red(`Update check failed: Received status code ${res.statusCode}`));
|
||||||
|
|
@ -115,7 +115,7 @@ program
|
||||||
|
|
||||||
// Accumulate response data chunks
|
// Accumulate response data chunks
|
||||||
let data = '';
|
let data = '';
|
||||||
res.on('data', chunk => data += chunk);
|
res.on('data', (chunk) => (data += chunk));
|
||||||
|
|
||||||
// Process complete response
|
// Process complete response
|
||||||
res.on('end', () => {
|
res.on('end', () => {
|
||||||
|
|
@ -125,7 +125,9 @@ program
|
||||||
|
|
||||||
// Compare versions using semver
|
// Compare versions using semver
|
||||||
if (semver.gt(latest, version)) {
|
if (semver.gt(latest, version)) {
|
||||||
console.log(chalk.bold.blue(`⚠️ ${packageName} update available: ${version} → ${latest}`));
|
console.log(
|
||||||
|
chalk.bold.blue(`⚠️ ${packageName} update available: ${version} → ${latest}`),
|
||||||
|
);
|
||||||
console.log(chalk.bold.blue('\nInstall latest by running:'));
|
console.log(chalk.bold.blue('\nInstall latest by running:'));
|
||||||
console.log(chalk.bold.magenta(` npm install ${packageName}@latest`));
|
console.log(chalk.bold.magenta(` npm install ${packageName}@latest`));
|
||||||
console.log(chalk.dim(' or'));
|
console.log(chalk.dim(' or'));
|
||||||
|
|
@ -141,12 +143,12 @@ program
|
||||||
});
|
});
|
||||||
|
|
||||||
// Handle network/connection errors
|
// Handle network/connection errors
|
||||||
req.on('error', error => {
|
req.on('error', (error) => {
|
||||||
console.error(chalk.red('Update check failed:'), error.message);
|
console.error(chalk.red('Update check failed:'), error.message);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Set 30 second timeout to prevent hanging
|
// Set 30 second timeout to prevent hanging
|
||||||
req.setTimeout(30000, () => {
|
req.setTimeout(30_000, () => {
|
||||||
req.destroy();
|
req.destroy();
|
||||||
console.error(chalk.red('Update check timed out'));
|
console.error(chalk.red('Update check timed out'));
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
* Reduces duplication and provides shared methods
|
* Reduces duplication and provides shared methods
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const path = require('path');
|
const path = require('node:path');
|
||||||
const fs = require('fs-extra');
|
const fs = require('fs-extra');
|
||||||
const yaml = require('js-yaml');
|
const yaml = require('js-yaml');
|
||||||
const chalk = require('chalk').default || require('chalk');
|
const chalk = require('chalk').default || require('chalk');
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue