timsquad 3.4.0 → 3.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.ko.md +4 -0
- package/README.md +4 -0
- package/dist/commands/audit.d.ts +22 -0
- package/dist/commands/audit.d.ts.map +1 -0
- package/dist/commands/audit.js +233 -0
- package/dist/commands/audit.js.map +1 -0
- package/dist/commands/compile.d.ts.map +1 -1
- package/dist/commands/compile.js +84 -3
- package/dist/commands/compile.js.map +1 -1
- package/dist/commands/daemon.d.ts.map +1 -1
- package/dist/commands/daemon.js +50 -3
- package/dist/commands/daemon.js.map +1 -1
- package/dist/commands/full.js +1 -0
- package/dist/commands/full.js.map +1 -1
- package/dist/commands/git/pr.js +6 -5
- package/dist/commands/git/pr.js.map +1 -1
- package/dist/commands/git/release.js +2 -7
- package/dist/commands/git/release.js.map +1 -1
- package/dist/commands/improve.js +2 -2
- package/dist/commands/improve.js.map +1 -1
- package/dist/commands/init.js +42 -6
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/log.d.ts.map +1 -1
- package/dist/commands/log.js +34 -2
- package/dist/commands/log.js.map +1 -1
- package/dist/commands/meta-index.d.ts.map +1 -1
- package/dist/commands/meta-index.js +30 -0
- package/dist/commands/meta-index.js.map +1 -1
- package/dist/commands/metrics.d.ts.map +1 -1
- package/dist/commands/metrics.js +6 -2
- package/dist/commands/metrics.js.map +1 -1
- package/dist/commands/retro.d.ts.map +1 -1
- package/dist/commands/retro.js +71 -14
- package/dist/commands/retro.js.map +1 -1
- package/dist/commands/session.js +3 -3
- package/dist/commands/session.js.map +1 -1
- package/dist/commands/skills.js +4 -7
- package/dist/commands/skills.js.map +1 -1
- package/dist/commands/status.js +1 -1
- package/dist/commands/status.js.map +1 -1
- package/dist/commands/upgrade.d.ts.map +1 -1
- package/dist/commands/upgrade.js +18 -1
- package/dist/commands/upgrade.js.map +1 -1
- package/dist/commands/workflow.d.ts +2 -0
- package/dist/commands/workflow.d.ts.map +1 -1
- package/dist/commands/workflow.js +180 -6
- package/dist/commands/workflow.js.map +1 -1
- package/dist/daemon/context-writer.d.ts +14 -0
- package/dist/daemon/context-writer.d.ts.map +1 -1
- package/dist/daemon/context-writer.js +29 -0
- package/dist/daemon/context-writer.js.map +1 -1
- package/dist/daemon/event-queue.d.ts +4 -0
- package/dist/daemon/event-queue.d.ts.map +1 -1
- package/dist/daemon/event-queue.js +107 -6
- package/dist/daemon/event-queue.js.map +1 -1
- package/dist/daemon/file-watcher.d.ts +14 -8
- package/dist/daemon/file-watcher.d.ts.map +1 -1
- package/dist/daemon/file-watcher.js +78 -41
- package/dist/daemon/file-watcher.js.map +1 -1
- package/dist/daemon/index.d.ts +1 -0
- package/dist/daemon/index.d.ts.map +1 -1
- package/dist/daemon/index.js +129 -53
- package/dist/daemon/index.js.map +1 -1
- package/dist/daemon/jsonl-watcher.d.ts +1 -0
- package/dist/daemon/jsonl-watcher.d.ts.map +1 -1
- package/dist/daemon/jsonl-watcher.js.map +1 -1
- package/dist/daemon/session-notes.d.ts +33 -0
- package/dist/daemon/session-notes.d.ts.map +1 -0
- package/dist/daemon/session-notes.js +74 -0
- package/dist/daemon/session-notes.js.map +1 -0
- package/dist/daemon/session-state.d.ts +8 -0
- package/dist/daemon/session-state.d.ts.map +1 -1
- package/dist/daemon/session-state.js +33 -0
- package/dist/daemon/session-state.js.map +1 -1
- package/dist/daemon/shutdown.d.ts.map +1 -1
- package/dist/daemon/shutdown.js +3 -1
- package/dist/daemon/shutdown.js.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/lib/agent-generator.d.ts +4 -0
- package/dist/lib/agent-generator.d.ts.map +1 -1
- package/dist/lib/agent-generator.js +63 -3
- package/dist/lib/agent-generator.js.map +1 -1
- package/dist/lib/compile-rules.d.ts +2 -0
- package/dist/lib/compile-rules.d.ts.map +1 -1
- package/dist/lib/compile-rules.js +2 -0
- package/dist/lib/compile-rules.js.map +1 -1
- package/dist/lib/compiler.d.ts +21 -1
- package/dist/lib/compiler.d.ts.map +1 -1
- package/dist/lib/compiler.js +113 -3
- package/dist/lib/compiler.js.map +1 -1
- package/dist/lib/config.d.ts +3 -0
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/config.js +17 -2
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/project.d.ts.map +1 -1
- package/dist/lib/project.js +8 -3
- package/dist/lib/project.js.map +1 -1
- package/dist/lib/skill-generator.d.ts +1 -1
- package/dist/lib/skill-generator.d.ts.map +1 -1
- package/dist/lib/skill-generator.js +39 -3
- package/dist/lib/skill-generator.js.map +1 -1
- package/dist/lib/ssot-map.d.ts +31 -0
- package/dist/lib/ssot-map.d.ts.map +1 -0
- package/dist/lib/ssot-map.js +76 -0
- package/dist/lib/ssot-map.js.map +1 -0
- package/dist/lib/template.js +1 -0
- package/dist/lib/template.js.map +1 -1
- package/dist/lib/workflow-state.d.ts +1 -1
- package/dist/lib/workflow-state.d.ts.map +1 -1
- package/dist/lib/workflow-state.js +1 -1
- package/dist/lib/workflow-state.js.map +1 -1
- package/dist/types/config.d.ts +10 -1
- package/dist/types/config.d.ts.map +1 -1
- package/dist/types/config.js +22 -17
- package/dist/types/config.js.map +1 -1
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +1 -0
- package/dist/types/index.js.map +1 -1
- package/dist/types/meta-index.d.ts +8 -0
- package/dist/types/meta-index.d.ts.map +1 -1
- package/dist/types/project.d.ts +1 -1
- package/dist/types/project.d.ts.map +1 -1
- package/dist/types/project.js.map +1 -1
- package/dist/types/ssot-map.d.ts +28 -0
- package/dist/types/ssot-map.d.ts.map +1 -0
- package/dist/types/ssot-map.js +6 -0
- package/dist/types/ssot-map.js.map +1 -0
- package/package.json +4 -4
- package/templates/base/agents/base/tsq-architect.md +2 -2
- package/templates/base/agents/base/tsq-librarian.md +45 -0
- package/templates/base/knowledge/checklists/plan-quality.md +31 -0
- package/templates/base/knowledge/checklists/stability-verification.md +14 -0
- package/templates/base/skills/_shared/naming-conventions.md +49 -0
- package/templates/base/skills/_template/SKILL.md +33 -17
- package/templates/base/skills/audit/SKILL.md +66 -0
- package/templates/base/skills/coding/SKILL.md +49 -29
- package/templates/base/skills/coding/rules/async-patterns.md +81 -0
- package/templates/base/skills/coding/rules/code-organization.md +80 -0
- package/templates/base/skills/coding/rules/error-handling.md +76 -0
- package/templates/base/skills/coding/rules/type-safety.md +85 -0
- package/templates/base/skills/controller/SKILL.md +50 -84
- package/templates/base/skills/controller/delegation/developer.md +25 -0
- package/templates/base/skills/controller/delegation/librarian.md +33 -0
- package/templates/base/skills/controller/delegation/reviewer.md +19 -0
- package/templates/base/skills/controller/memory/.gitkeep +0 -0
- package/templates/base/skills/controller/triggers/phase-complete.md +25 -0
- package/templates/base/skills/controller/triggers/sequence-complete.md +15 -0
- package/templates/base/skills/controller/triggers/ssot-changed.md +14 -0
- package/templates/base/skills/controller/triggers/task-complete.md +14 -0
- package/templates/base/skills/database/SKILL.md +8 -25
- package/templates/base/skills/database/rules/query-optimization.md +32 -0
- package/templates/base/skills/database/rules/supabase-patterns.md +94 -0
- package/templates/base/skills/librarian/SKILL.md +53 -0
- package/templates/base/skills/main-session-constraints/SKILL.md +62 -0
- package/templates/base/skills/methodology/tdd/SKILL.md +6 -0
- package/templates/base/skills/product-audit/SKILL.md +115 -0
- package/templates/base/skills/product-audit/checklists/01-security.md +86 -0
- package/templates/base/skills/product-audit/checklists/02-performance.md +67 -0
- package/templates/base/skills/product-audit/checklists/03-seo.md +46 -0
- package/templates/base/skills/product-audit/checklists/04-accessibility.md +66 -0
- package/templates/base/skills/product-audit/checklists/05-ui-ux.md +50 -0
- package/templates/base/skills/product-audit/checklists/06-architecture.md +53 -0
- package/templates/base/skills/product-audit/checklists/07-functional-requirements.md +55 -0
- package/templates/base/skills/product-audit/rules/audit-protocol.md +136 -0
- package/templates/base/skills/product-audit/rules/false-positive-guard.md +81 -0
- package/templates/base/skills/product-audit/rules/scoring-criteria.md +113 -0
- package/templates/base/skills/product-audit/templates/improvement-plan-template.md +60 -0
- package/templates/base/skills/product-audit/templates/report-template.md +88 -0
- package/templates/base/skills/prompt-engineering/SKILL.md +54 -73
- package/templates/base/skills/retrospective/SKILL.md +70 -95
- package/templates/base/skills/retrospective/references/improvement-template.md +26 -0
- package/templates/base/skills/review/SKILL.md +72 -0
- package/templates/base/skills/security/SKILL.md +50 -37
- package/templates/base/skills/security/rules/auth-patterns.md +62 -0
- package/templates/base/skills/security/rules/dependency-security.md +69 -0
- package/templates/base/skills/security/rules/input-validation.md +68 -0
- package/templates/base/skills/security/rules/secrets-management.md +65 -0
- package/templates/base/skills/spec/SKILL.md +60 -0
- package/templates/base/skills/stability-verification/SKILL.md +64 -0
- package/templates/base/skills/stability-verification/references/release-checklist.md +34 -0
- package/templates/base/skills/stability-verification/references/security-fix-patterns.md +112 -0
- package/templates/base/skills/stability-verification/rules/verification-layers.md +67 -0
- package/templates/base/skills/stability-verification/rules/verification-workflow.md +69 -0
- package/templates/base/skills/stability-verification/scripts/verify.sh +294 -0
- package/templates/base/skills/testing/SKILL.md +33 -25
- package/templates/base/skills/testing/references/e2e-stability.md +33 -0
- package/templates/base/skills/tsq-cli/SKILL.md +73 -0
- package/templates/base/skills/tsq-cli/references/cli-reference.md +92 -0
- package/templates/base/skills/tsq-protocol/SKILL.md +41 -25
- package/templates/base/skills/typescript/SKILL.md +3 -9
- package/templates/base/timsquad/ssot/test-spec.template.md +11 -1
- package/templates/base/timsquad/ssot-map.template.yaml +41 -0
- package/templates/platforms/claude-code/rules/api-conventions.md +12 -0
- package/templates/platforms/claude-code/rules/build-gate.md +28 -0
- package/templates/platforms/claude-code/rules/completion-verification.md +30 -0
- package/templates/platforms/claude-code/rules/context-monitor.md +23 -0
- package/templates/platforms/claude-code/rules/librarian-constraints.md +11 -0
- package/templates/platforms/claude-code/rules/plan-review.md +45 -0
- package/templates/platforms/claude-code/rules/quality-guards.md +43 -0
- package/templates/platforms/claude-code/rules/session-notes.md +18 -0
- package/templates/platforms/claude-code/rules/skill-suggest.md +27 -0
- package/templates/platforms/claude-code/rules/test-conventions.md +13 -0
- package/templates/platforms/claude-code/scripts/build-gate.sh +73 -0
- package/templates/platforms/claude-code/scripts/change-scope-guard.sh +113 -0
- package/templates/platforms/claude-code/scripts/completion-guard.sh +122 -24
- package/templates/platforms/claude-code/scripts/context-restore.sh +68 -0
- package/templates/platforms/claude-code/scripts/e2e-commit-gate.sh +70 -0
- package/templates/platforms/claude-code/scripts/e2e-marker.sh +51 -0
- package/templates/platforms/claude-code/scripts/phase-guard.sh +5 -5
- package/templates/platforms/claude-code/scripts/pre-compact.sh +70 -0
- package/templates/platforms/claude-code/scripts/safe-guard.sh +83 -0
- package/templates/platforms/claude-code/scripts/skill-inject.sh +216 -0
- package/templates/platforms/claude-code/scripts/skill-rules.json +95 -0
- package/templates/platforms/claude-code/scripts/skill-suggest.sh +105 -0
- package/templates/platforms/claude-code/scripts/subagent-inject.sh +53 -0
- package/templates/platforms/claude-code/settings.json +71 -9
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Dependency Security
|
|
3
|
+
impact: HIGH
|
|
4
|
+
tags: security, dependencies, npm-audit, supply-chain, license
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Dependency Security
|
|
8
|
+
|
|
9
|
+
## npm audit
|
|
10
|
+
```bash
|
|
11
|
+
# Check for known vulnerabilities
|
|
12
|
+
npm audit
|
|
13
|
+
|
|
14
|
+
# Fix automatically where possible
|
|
15
|
+
npm audit fix
|
|
16
|
+
|
|
17
|
+
# Fail CI on critical/high vulnerabilities
|
|
18
|
+
npm audit --audit-level=high
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
- Run `npm audit` in CI pipelines; block merges on high/critical findings
|
|
22
|
+
- Review advisories before applying `npm audit fix --force` (may include breaking changes)
|
|
23
|
+
- Use tools like `socket.dev` or `snyk` for deeper analysis
|
|
24
|
+
|
|
25
|
+
## Lockfile Integrity
|
|
26
|
+
- Always commit `package-lock.json` to version control
|
|
27
|
+
- Use `npm ci` in CI/CD (respects lockfile exactly, fails on mismatch)
|
|
28
|
+
- Review lockfile diffs in PRs for unexpected changes
|
|
29
|
+
```bash
|
|
30
|
+
# CI install — strict, reproducible
|
|
31
|
+
npm ci
|
|
32
|
+
|
|
33
|
+
# Never use `npm install` in CI — it can modify the lockfile
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Supply Chain Attack Prevention
|
|
37
|
+
- Pin exact versions for critical dependencies
|
|
38
|
+
- Verify package provenance when available (`npm audit signatures`)
|
|
39
|
+
- Be cautious with post-install scripts; audit new dependencies before adding
|
|
40
|
+
```bash
|
|
41
|
+
# Check what scripts a package runs
|
|
42
|
+
npm explain <package>
|
|
43
|
+
npm pack <package> --dry-run # inspect contents before install
|
|
44
|
+
|
|
45
|
+
# Disable scripts for untrusted packages
|
|
46
|
+
npm install --ignore-scripts <package>
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
- Prefer well-maintained packages with large user bases
|
|
50
|
+
- Monitor for typosquatting (e.g., `lodash` vs `l0dash`)
|
|
51
|
+
- Use `npm-shrinkwrap.json` for published packages requiring locked deps
|
|
52
|
+
|
|
53
|
+
## License Compliance
|
|
54
|
+
```bash
|
|
55
|
+
# Check licenses of all dependencies
|
|
56
|
+
npx license-checker --summary
|
|
57
|
+
npx license-checker --failOn 'GPL-3.0;AGPL-3.0'
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
- Define an allowlist of acceptable licenses for the project
|
|
61
|
+
- Block copyleft licenses (GPL, AGPL) in proprietary codebases
|
|
62
|
+
- Document license policy and automate checks in CI
|
|
63
|
+
|
|
64
|
+
## Checklist
|
|
65
|
+
- `npm audit` runs in CI; high/critical findings block deployment
|
|
66
|
+
- `package-lock.json` committed; CI uses `npm ci`
|
|
67
|
+
- New dependencies reviewed for maintenance status, size, and scripts
|
|
68
|
+
- License compliance checked automatically; policy documented
|
|
69
|
+
- Lockfile diffs reviewed in pull requests
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Input Validation
|
|
3
|
+
impact: CRITICAL
|
|
4
|
+
tags: security, validation, sanitization, injection
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Input Validation
|
|
8
|
+
|
|
9
|
+
## Principle
|
|
10
|
+
Never trust user input. Validate, sanitize, and constrain all external data before processing.
|
|
11
|
+
|
|
12
|
+
## Allowlist Over Denylist
|
|
13
|
+
```typescript
|
|
14
|
+
// Bad: denylist — easy to bypass
|
|
15
|
+
const forbidden = ['<script>', 'onclick', 'onerror'];
|
|
16
|
+
if (forbidden.some(f => input.includes(f))) throw new Error('Invalid');
|
|
17
|
+
|
|
18
|
+
// Good: allowlist — only permit known-safe values
|
|
19
|
+
const ALLOWED_ROLES = ['admin', 'editor', 'viewer'] as const;
|
|
20
|
+
if (!ALLOWED_ROLES.includes(role)) throw new Error('Invalid role');
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Schema Validation
|
|
24
|
+
```typescript
|
|
25
|
+
import { z } from 'zod';
|
|
26
|
+
|
|
27
|
+
const UserInput = z.object({
|
|
28
|
+
name: z.string().min(1).max(100).trim(),
|
|
29
|
+
email: z.string().email().max(254),
|
|
30
|
+
age: z.number().int().min(0).max(150),
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
// Validate at boundary (controller/handler)
|
|
34
|
+
const data = UserInput.parse(req.body);
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Parameterized Queries
|
|
38
|
+
```typescript
|
|
39
|
+
// Bad: string interpolation — SQL injection risk
|
|
40
|
+
const q = `SELECT * FROM users WHERE id = '${id}'`;
|
|
41
|
+
|
|
42
|
+
// Good: parameterized query
|
|
43
|
+
const q = 'SELECT * FROM users WHERE id = $1';
|
|
44
|
+
await db.query(q, [id]);
|
|
45
|
+
|
|
46
|
+
// Good: ORM with type-safe parameters
|
|
47
|
+
await userRepo.findOneBy({ id: parseInt(id, 10) });
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Sanitize HTML Output
|
|
51
|
+
```typescript
|
|
52
|
+
// Bad
|
|
53
|
+
element.innerHTML = userInput;
|
|
54
|
+
|
|
55
|
+
// Good: escape or use textContent
|
|
56
|
+
element.textContent = userInput;
|
|
57
|
+
|
|
58
|
+
// Good: DOMPurify for rich content
|
|
59
|
+
import DOMPurify from 'dompurify';
|
|
60
|
+
element.innerHTML = DOMPurify.sanitize(userInput);
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Checklist
|
|
64
|
+
- Validate type, length, format, and range at the application boundary
|
|
65
|
+
- Use allowlists for enumerated values (roles, statuses, types)
|
|
66
|
+
- Use parameterized queries or ORM — never interpolate user input into SQL
|
|
67
|
+
- Sanitize output based on context (HTML, URL, SQL, shell)
|
|
68
|
+
- Reject unexpected fields; do not pass raw request bodies to business logic
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Secrets Management
|
|
3
|
+
impact: HIGH
|
|
4
|
+
tags: security, secrets, env, gitignore, rotation
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Secrets Management
|
|
8
|
+
|
|
9
|
+
## Never Hardcode Secrets
|
|
10
|
+
```typescript
|
|
11
|
+
// Bad: hardcoded secret
|
|
12
|
+
const API_KEY = 'sk-1234567890abcdef';
|
|
13
|
+
const DB_URL = 'postgres://admin:password@db:5432/prod';
|
|
14
|
+
|
|
15
|
+
// Good: environment variables
|
|
16
|
+
const API_KEY = process.env.API_KEY;
|
|
17
|
+
const DB_URL = process.env.DATABASE_URL;
|
|
18
|
+
|
|
19
|
+
// Better: secret manager for production
|
|
20
|
+
const API_KEY = await secretManager.getSecret('api-key');
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Environment Variables
|
|
24
|
+
- Use `.env` files for local development only
|
|
25
|
+
- Load with `dotenv` at application entry point, not in library code
|
|
26
|
+
- Validate required env vars at startup
|
|
27
|
+
```typescript
|
|
28
|
+
const required = ['DATABASE_URL', 'JWT_SECRET', 'API_KEY'];
|
|
29
|
+
for (const key of required) {
|
|
30
|
+
if (!process.env[key]) throw new Error(`Missing env var: ${key}`);
|
|
31
|
+
}
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## .gitignore Rules
|
|
35
|
+
```gitignore
|
|
36
|
+
# Must be in .gitignore — never commit secrets
|
|
37
|
+
.env
|
|
38
|
+
.env.local
|
|
39
|
+
.env.*.local
|
|
40
|
+
*.pem
|
|
41
|
+
*.key
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
- Use `.env.example` with placeholder values for documentation
|
|
45
|
+
- Run `git log --all -p -- .env` to verify secrets were never committed
|
|
46
|
+
- If a secret was committed, rotate it immediately — git history persists
|
|
47
|
+
|
|
48
|
+
## Secret Rotation
|
|
49
|
+
- Rotate secrets on a regular schedule (90 days recommended)
|
|
50
|
+
- Support dual-read during rotation (accept old + new key simultaneously)
|
|
51
|
+
- Automate rotation via secret manager (AWS Secrets Manager, Vault, etc.)
|
|
52
|
+
- Revoke old secrets after confirming the new ones work
|
|
53
|
+
|
|
54
|
+
## Production Practices
|
|
55
|
+
- Use a dedicated secret manager (AWS Secrets Manager, HashiCorp Vault, GCP Secret Manager)
|
|
56
|
+
- Grant least-privilege access to secrets per service
|
|
57
|
+
- Audit secret access logs regularly
|
|
58
|
+
- Never log secret values; mask them in error output
|
|
59
|
+
|
|
60
|
+
## Checklist
|
|
61
|
+
- No secrets in source code, config files, or container images
|
|
62
|
+
- `.env` and key files listed in `.gitignore`
|
|
63
|
+
- Required env vars validated at startup with clear error messages
|
|
64
|
+
- Secrets rotated on schedule; old secrets revoked
|
|
65
|
+
- Production uses a secret manager, not plain env vars
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: spec
|
|
3
|
+
description: |
|
|
4
|
+
SSOT(Single Source of Truth) 문서 존재 여부를 확인하고, 미존재 시 구현 전 스펙 작성을 안내한다.
|
|
5
|
+
`/spec <기능명>`으로 호출하면 해당 기능의 SSOT 문서를 찾아 상태를 보고한다.
|
|
6
|
+
스펙 없이 구현하는 것을 방지하여 문서-코드 일관성을 유지한다.
|
|
7
|
+
version: "1.0.0"
|
|
8
|
+
tags: [spec, ssot, gate, documentation]
|
|
9
|
+
depends_on: [tsq-protocol]
|
|
10
|
+
conflicts_with: []
|
|
11
|
+
user-invocable: true
|
|
12
|
+
argument-hint: "[기능명] — SSOT 문서 존재 여부 확인"
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
# Spec Gate
|
|
16
|
+
|
|
17
|
+
SSOT 문서 존재 여부를 확인하여 스펙 없는 구현을 방지한다.
|
|
18
|
+
|
|
19
|
+
## Contract
|
|
20
|
+
|
|
21
|
+
- **Trigger**: `/spec` 호출 또는 구현 시작 전 자동 확인
|
|
22
|
+
- **Input**: `$ARGUMENTS` (기능명) 또는 미지정 시 전체 SSOT 상태
|
|
23
|
+
- **Output**: SSOT 상태 리포트 (존재/stale/미존재) + 권장 액션
|
|
24
|
+
- **Error**: SSOT 디렉토리 자체가 없을 경우 "NOT FOUND" 안내
|
|
25
|
+
- **Dependencies**: tsq-protocol
|
|
26
|
+
|
|
27
|
+
## Protocol
|
|
28
|
+
|
|
29
|
+
1. **SSOT 검색**: `$ARGUMENTS`로 전달된 기능명으로 `.timsquad/ssot/` 디렉토리 탐색
|
|
30
|
+
2. **존재 확인**: 해당 기능의 스펙 문서(PRD, 설계문서, API 스펙) 존재 여부 판단
|
|
31
|
+
3. **상태 판정**:
|
|
32
|
+
- **존재 + 최신**: 스펙 요약 출력 + "구현 가능" 안내
|
|
33
|
+
- **존재 + stale**: "스펙 갱신 필요" + `tsq compile` 재실행 안내
|
|
34
|
+
- **미존재**: advisory 경고 + 스펙 작성 가이드 제공
|
|
35
|
+
4. **결과 리포트**: 상태 + 권장 액션을 구조화하여 출력
|
|
36
|
+
|
|
37
|
+
## Verification
|
|
38
|
+
|
|
39
|
+
| Check | Method | Pass Criteria |
|
|
40
|
+
|-------|--------|---------------|
|
|
41
|
+
| SSOT 파일 존재 | `.timsquad/ssot/` 탐색 | 관련 문서 1개 이상 |
|
|
42
|
+
| stale 여부 | compile-manifest hash 비교 | hash 일치 |
|
|
43
|
+
| 스펙 커버리지 | 기능 키워드 매칭 | 해당 기능 언급 존재 |
|
|
44
|
+
|
|
45
|
+
## Quick Rules
|
|
46
|
+
|
|
47
|
+
### Gate 동작
|
|
48
|
+
- **미존재 시**: advisory 경고 (차단 아님)
|
|
49
|
+
```
|
|
50
|
+
[SPEC GATE] 기능 "{name}"에 대한 SSOT 문서가 없습니다.
|
|
51
|
+
스펙 먼저 작성하세요: .timsquad/ssot/{name}.md
|
|
52
|
+
가이드: PRD → 설계문서 → Compiled Spec 순서
|
|
53
|
+
```
|
|
54
|
+
- **stale 시**: `tsq compile` 재실행 안내
|
|
55
|
+
```
|
|
56
|
+
[SPEC GATE] SSOT 문서가 최신이 아닙니다. `tsq compile` 재실행 필요.
|
|
57
|
+
```
|
|
58
|
+
- **Phase gate에서만 실제 차단** (일반 사용 시 advisory)
|
|
59
|
+
- `$ARGUMENTS` 미지정 시 전체 SSOT 상태 요약
|
|
60
|
+
- PRD, 설계문서, API 스펙 모두 SSOT로 인정
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: stability-verification
|
|
3
|
+
description: |
|
|
4
|
+
프로젝트 안정성 검증 스킬. 릴리스/스프린트 완료 전 6-Layer 자동+수동 검증 수행.
|
|
5
|
+
L0(정적분석) → L1(유닛테스트) → L2(보안스캔) → L3(쉘스크립트) → L4(통합) → L5(패키지).
|
|
6
|
+
각 레이어는 fail-closed(기본) 또는 fail-open 정책 적용.
|
|
7
|
+
사용 시점: 릴리스 전, 스프린트 완료 시, 보안 감사 요청 시.
|
|
8
|
+
version: "1.0.0"
|
|
9
|
+
tags: [verification, security, quality, release]
|
|
10
|
+
user-invocable: false
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# Stability Verification
|
|
14
|
+
|
|
15
|
+
프로젝트 안정성을 6-Layer 피라미드로 검증한다. 빠르고 저렴한 검사부터 실행하여 초기 실패를 빠르게 잡는다.
|
|
16
|
+
|
|
17
|
+
## Philosophy
|
|
18
|
+
|
|
19
|
+
- **빠른 것부터**: L0(5초) → L5(30초) 순서로 실행, 첫 실패 시 멈춤
|
|
20
|
+
- **Fail-closed 기본**: 모든 레이어는 기본 차단, 명시적 opt-out만 허용
|
|
21
|
+
- **자동 + 수동 병행**: L0~L5는 스크립트 자동화, L6는 사람이 확인
|
|
22
|
+
|
|
23
|
+
## Resources
|
|
24
|
+
|
|
25
|
+
| Priority | Type | Resource | Description |
|
|
26
|
+
|----------|------|----------|-------------|
|
|
27
|
+
| CRITICAL | script | [verify.sh](scripts/verify.sh) | 전체 레이어 오케스트레이터 |
|
|
28
|
+
| CRITICAL | rule | [verification-layers](rules/verification-layers.md) | 6-Layer 정의 + 실패 정책 |
|
|
29
|
+
| HIGH | rule | [verification-workflow](rules/verification-workflow.md) | 검증 실행 워크플로우 패턴 |
|
|
30
|
+
| HIGH | ref | [security-fix-patterns](references/security-fix-patterns.md) | 취약점별 수정 패턴 모음 |
|
|
31
|
+
| MEDIUM | ref | [release-checklist](references/release-checklist.md) | L6 수동 릴리스 체크리스트 |
|
|
32
|
+
|
|
33
|
+
## Quick Rules
|
|
34
|
+
|
|
35
|
+
### 검증 실행
|
|
36
|
+
- `bash .claude/skills/stability-verification/scripts/verify.sh` 로 전체 실행
|
|
37
|
+
- `--layer L0` 으로 특정 레이어만 실행
|
|
38
|
+
- `--skip L3` 으로 특정 레이어 건너뛰기
|
|
39
|
+
|
|
40
|
+
### Fail Policy
|
|
41
|
+
- L0(정적분석), L1(유닛테스트), L5(패키지): **항상 fail-closed**
|
|
42
|
+
- L2(보안): critical/high = fail-closed, moderate/low = fail-open
|
|
43
|
+
- L3(쉘테스트), L4(통합): fail-closed, `--skip` 가능
|
|
44
|
+
|
|
45
|
+
### 이슈 발견 시 수정 워크플로우
|
|
46
|
+
1. 이슈 분류 (CRITICAL > HIGH > MEDIUM > LOW)
|
|
47
|
+
2. 수정 패턴 리서치 (스킬 검색 + 웹 참조)
|
|
48
|
+
3. 수정 계획 수립 (패턴 기반)
|
|
49
|
+
4. 수정 적용 + 재검증
|
|
50
|
+
|
|
51
|
+
## Checklist
|
|
52
|
+
|
|
53
|
+
| Priority | Item |
|
|
54
|
+
|----------|------|
|
|
55
|
+
| CRITICAL | `tsc --noEmit` 에러 0개 |
|
|
56
|
+
| CRITICAL | `npm run test:unit` 전체 통과 |
|
|
57
|
+
| CRITICAL | `execSync` 대신 `execFileSync` (커맨드 인젝션 방지) |
|
|
58
|
+
| HIGH | `shellcheck --severity=warning` 모든 .sh 경고 0개 |
|
|
59
|
+
| HIGH | `npm audit --audit-level=high` 취약점 0개 |
|
|
60
|
+
| HIGH | JSON 출력은 `jq -n --arg` 사용 (문자열 보간 금지) |
|
|
61
|
+
| HIGH | jq 호출에 `|| echo ""` fail-open 폴백 |
|
|
62
|
+
| MEDIUM | `npm pack --dry-run` 의도한 파일만 포함 |
|
|
63
|
+
| MEDIUM | `.gitignore`에 .env, *.pem, *.key 포함 |
|
|
64
|
+
| MEDIUM | `grep -- "$var"` 분리자 사용 |
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Release Checklist
|
|
3
|
+
category: guide
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# L6: 릴리스 체크리스트 (수동)
|
|
7
|
+
|
|
8
|
+
릴리스 전 사람이 확인하는 항목. `verify.sh`가 커버하지 않는 영역.
|
|
9
|
+
|
|
10
|
+
## 버전 관리
|
|
11
|
+
- [ ] `package.json` version이 의도한 릴리스 버전과 일치
|
|
12
|
+
- [ ] CHANGELOG.md에 모든 변경사항 반영
|
|
13
|
+
- [ ] Breaking changes 별도 섹션에 기술
|
|
14
|
+
|
|
15
|
+
## 문서
|
|
16
|
+
- [ ] README.md에 새 기능/명령 반영
|
|
17
|
+
- [ ] PRD.md 버전 히스토리 업데이트
|
|
18
|
+
- [ ] 메모리 파일 현재 상태 반영
|
|
19
|
+
|
|
20
|
+
## Git
|
|
21
|
+
- [ ] `main` 브랜치에서 릴리스 (clean working tree)
|
|
22
|
+
- [ ] 모든 변경이 커밋됨 (`git status` clean)
|
|
23
|
+
- [ ] 릴리스 태그 생성 (`git tag v{version}`)
|
|
24
|
+
|
|
25
|
+
## npm 배포
|
|
26
|
+
- [ ] `npm run build` 성공
|
|
27
|
+
- [ ] `npm pack --dry-run` 검토 — 의도한 파일만 포함
|
|
28
|
+
- [ ] `templates/domains/` 미포함 (유료 콘텐츠)
|
|
29
|
+
- [ ] `.env`, `*.key` 등 민감 파일 미포함
|
|
30
|
+
- [ ] `npm publish` 실행
|
|
31
|
+
|
|
32
|
+
## 배포 후
|
|
33
|
+
- [ ] `npm info timsquad version` 으로 배포 확인
|
|
34
|
+
- [ ] GitHub Release 생성 (해당 시)
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Security Fix Patterns
|
|
3
|
+
category: reference
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# 보안 수정 패턴 모음
|
|
7
|
+
|
|
8
|
+
출처: OWASP Node.js Cheat Sheet, ShellCheck Wiki, BashFAQ/048, Shellharden
|
|
9
|
+
|
|
10
|
+
## 1. 커맨드 인젝션 (Node.js)
|
|
11
|
+
|
|
12
|
+
### Incorrect
|
|
13
|
+
```typescript
|
|
14
|
+
execSync(`git clone "${url}" "${dir}"`);
|
|
15
|
+
const sanitized = input.replace(/["`$\\]/g, '');
|
|
16
|
+
execSync(`command "${sanitized}"`);
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
### Correct
|
|
20
|
+
```typescript
|
|
21
|
+
import { execFileSync } from 'child_process';
|
|
22
|
+
execFileSync('git', ['clone', url, dir]); // shell: false (기본값)
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
**원칙**: `execSync` → `execFileSync` 배열 기반. 새니타이징은 불완전하므로 의존하지 않는다.
|
|
26
|
+
|
|
27
|
+
## 2. JSON 구성 (Shell Script)
|
|
28
|
+
|
|
29
|
+
### Incorrect
|
|
30
|
+
```bash
|
|
31
|
+
echo "{\"key\":\"$VAR\"}" # $VAR에 " 포함 시 깨짐
|
|
32
|
+
cat > file.json << EOF
|
|
33
|
+
{"key": "$VAR"}
|
|
34
|
+
EOF
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### Correct
|
|
38
|
+
```bash
|
|
39
|
+
jq -n --arg key "$VAR" '{"key": $key}'
|
|
40
|
+
jq -n --arg k1 "$A" --arg k2 "$B" '{a: $k1, b: $k2}'
|
|
41
|
+
jq -n --argjson num "$NUMBER" '{count: $num}' # 숫자/불린
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## 3. jq + set -e Fail-Open
|
|
45
|
+
|
|
46
|
+
### Incorrect
|
|
47
|
+
```bash
|
|
48
|
+
set -e
|
|
49
|
+
VAR=$(echo "$INPUT" | jq -r '.field' 2>/dev/null) # jq 실패 시 스크립트 종료
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### Correct
|
|
53
|
+
```bash
|
|
54
|
+
set -e
|
|
55
|
+
VAR=$(echo "$INPUT" | jq -r '.field // ""' 2>/dev/null || echo "")
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## 4. source 대신 안전한 설정 읽기
|
|
59
|
+
|
|
60
|
+
### Incorrect
|
|
61
|
+
```bash
|
|
62
|
+
source "$HOME/.config" # 임의 코드 실행 가능
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### Correct
|
|
66
|
+
```bash
|
|
67
|
+
VALUE=$(grep -m1 '^KEY=' "$HOME/.config" 2>/dev/null | cut -d'=' -f2- | tr -d '"')
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## 5. grep 변수 안전 사용
|
|
71
|
+
|
|
72
|
+
### Incorrect
|
|
73
|
+
```bash
|
|
74
|
+
grep "$var" file # $var가 "-e ..."이면 플래그로 해석
|
|
75
|
+
grep "^${file}" output # $file에 . + [ 등 regex 특수문자
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### Correct
|
|
79
|
+
```bash
|
|
80
|
+
grep -- "$var" file # -- 로 옵션 종료
|
|
81
|
+
grep -F -- "$file" output # -F 로 리터럴 매칭
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## 6. 사용자 입력 검증
|
|
85
|
+
|
|
86
|
+
### Incorrect
|
|
87
|
+
```bash
|
|
88
|
+
PROJECT_NAME="$1"
|
|
89
|
+
echo "name: $PROJECT_NAME" > config.yaml # 인젝션 가능
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### Correct
|
|
93
|
+
```bash
|
|
94
|
+
if [[ ! "$1" =~ ^[a-zA-Z][a-zA-Z0-9_-]{0,63}$ ]]; then
|
|
95
|
+
echo "Error: invalid name" >&2; exit 1
|
|
96
|
+
fi
|
|
97
|
+
PROJECT_NAME="$1"
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## 7. .gitignore 보안 항목
|
|
101
|
+
|
|
102
|
+
```gitignore
|
|
103
|
+
.env
|
|
104
|
+
.env.*
|
|
105
|
+
!.env.example
|
|
106
|
+
*.pem
|
|
107
|
+
*.key
|
|
108
|
+
*.p12
|
|
109
|
+
*.pfx
|
|
110
|
+
credentials.json
|
|
111
|
+
service-account*.json
|
|
112
|
+
```
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Verification Layers
|
|
3
|
+
description: 6-Layer 안정성 검증 정의. 각 레이어의 검사 항목, 도구, 실패 정책.
|
|
4
|
+
globs:
|
|
5
|
+
- "**/*"
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Verification Layers
|
|
9
|
+
|
|
10
|
+
## L0: 정적 분석 (Syntax/Lint) — ~5초, Fail-Closed
|
|
11
|
+
|
|
12
|
+
| 검사 | 명령 | 대상 |
|
|
13
|
+
|------|------|------|
|
|
14
|
+
| TypeScript 컴파일 | `tsc --noEmit` | src/**/*.ts |
|
|
15
|
+
| ShellCheck | `shellcheck --severity=warning` | **/*.sh |
|
|
16
|
+
| Bash 구문 | `bash -n` | **/*.sh |
|
|
17
|
+
| JSON 유효성 | `jq empty < file.json` | **/*.json |
|
|
18
|
+
|
|
19
|
+
## L1: 유닛 테스트 — ~10초, Fail-Closed
|
|
20
|
+
|
|
21
|
+
| 검사 | 명령 |
|
|
22
|
+
|------|------|
|
|
23
|
+
| 전체 유닛 테스트 | `npm run test:unit` |
|
|
24
|
+
| 신규 모듈 테스트 존재 확인 | 수동 확인 |
|
|
25
|
+
|
|
26
|
+
## L2: 보안 스캔 — ~15초, Critical=Fail-Closed
|
|
27
|
+
|
|
28
|
+
| 검사 | 명령 | 실패 정책 |
|
|
29
|
+
|------|------|-----------|
|
|
30
|
+
| npm 취약점 | `npm audit --audit-level=high` | critical/high: 차단, moderate/low: 경고 |
|
|
31
|
+
| execSync 인젝션 | `grep -rn 'execSync(' src/` → 변수 보간 확인 | Fail-closed |
|
|
32
|
+
| eval 사용 | `grep -rn 'eval ' **/*.sh` | Fail-closed |
|
|
33
|
+
| 하드코딩 시크릿 | `check-secrets.sh` 또는 수동 검색 | Fail-closed |
|
|
34
|
+
| JSON 문자열 보간 | 쉘 스크립트에서 `echo "{...\"$VAR\"}"` 패턴 확인 | HIGH |
|
|
35
|
+
| .gitignore 보안 | .env, *.pem, *.key 항목 존재 확인 | MEDIUM |
|
|
36
|
+
|
|
37
|
+
## L3: 쉘 스크립트 테스트 — ~10초, Fail-Closed
|
|
38
|
+
|
|
39
|
+
| 검사 | 방법 |
|
|
40
|
+
|------|------|
|
|
41
|
+
| 빈 stdin → fail-open | `echo "" \| bash script.sh` |
|
|
42
|
+
| malformed JSON → fail-open | `echo "not json" \| bash script.sh` |
|
|
43
|
+
| 정상 입력 → 기대 출력 | 정상 JSON 파이프 |
|
|
44
|
+
| 특수문자 입력 → JSON 무결성 | 인용부호/개행 포함 입력 |
|
|
45
|
+
| jq fallback 동작 확인 | `|| echo ""` 패턴 존재 확인 |
|
|
46
|
+
|
|
47
|
+
## L4: 통합/E2E 테스트 — ~30초, Fail-Closed
|
|
48
|
+
|
|
49
|
+
| 검사 | 명령 |
|
|
50
|
+
|------|------|
|
|
51
|
+
| 통합 테스트 | `npm run test:integration` (있을 경우) |
|
|
52
|
+
| E2E 테스트 | `npm run test:e2e` (있을 경우) |
|
|
53
|
+
| CLI 스모크 테스트 | `node bin/tsq.js --version` |
|
|
54
|
+
|
|
55
|
+
## L5: 패키지 무결성 — ~10초, Fail-Closed
|
|
56
|
+
|
|
57
|
+
| 검사 | 명령 |
|
|
58
|
+
|------|------|
|
|
59
|
+
| 빌드 성공 | `npm run build` |
|
|
60
|
+
| 버전 출력 | `node bin/tsq.js --version` |
|
|
61
|
+
| 패키지 내용물 | `npm pack --dry-run` |
|
|
62
|
+
| 민감 파일 미포함 | grep .env/.key/.pem in pack output |
|
|
63
|
+
| 유료 콘텐츠 미포함 | `templates/domains/` 미포함 확인 |
|
|
64
|
+
|
|
65
|
+
## L6: 릴리스 준비 (수동) — Fail-Closed
|
|
66
|
+
|
|
67
|
+
`references/release-checklist.md` 참조.
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Verification Workflow
|
|
3
|
+
description: 안정성 검증 실행 워크플로우. 검증→발견→리서치→수정→재검증 사이클.
|
|
4
|
+
globs:
|
|
5
|
+
- "**/*"
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Verification Workflow
|
|
9
|
+
|
|
10
|
+
## 전체 사이클
|
|
11
|
+
|
|
12
|
+
```
|
|
13
|
+
1. 리서치 → 2. 계획 → 3. 스킬 생성/갱신 → 4. 검증 실행 → 5. 이슈 수정 → 6. 재검증
|
|
14
|
+
↑ |
|
|
15
|
+
└──────────────────── 이슈 발견 시 수정 패턴 리서치 ──────────────┘
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Phase 1: 리서치
|
|
19
|
+
|
|
20
|
+
검증 시작 전 반드시 수행:
|
|
21
|
+
|
|
22
|
+
1. **스킬 검색**: `npx skills find "code quality verification"` 등으로 관련 스킬 탐색
|
|
23
|
+
2. **웹 참조**: OWASP, ShellCheck Wiki, npm security best practices 등 참조
|
|
24
|
+
3. **기존 스킬 확인**: `stability-verification` 스킬이 이미 있으면 갱신 여부 판단
|
|
25
|
+
|
|
26
|
+
## Phase 2: 계획
|
|
27
|
+
|
|
28
|
+
리서치 결과를 바탕으로 검증 계획 수립:
|
|
29
|
+
|
|
30
|
+
- 어떤 레이어를 실행할 것인가 (L0~L5 중 해당되는 것)
|
|
31
|
+
- 각 레이어의 fail policy (closed/open)
|
|
32
|
+
- 검증 대상 범위 (전체 프로젝트 vs 변경분)
|
|
33
|
+
|
|
34
|
+
## Phase 3: 검증 실행
|
|
35
|
+
|
|
36
|
+
`verify.sh` 또는 수동으로 각 레이어 순차 실행.
|
|
37
|
+
|
|
38
|
+
## Phase 4: 이슈 발견 시 수정 워크플로우
|
|
39
|
+
|
|
40
|
+
**중요**: 발견 즉시 수정하지 않는다. 리서치 먼저.
|
|
41
|
+
|
|
42
|
+
### 수정 프로세스
|
|
43
|
+
|
|
44
|
+
```
|
|
45
|
+
이슈 분류 (CRITICAL/HIGH/MEDIUM/LOW)
|
|
46
|
+
→ 수정 패턴 리서치
|
|
47
|
+
- 스킬 검색: `npx skills find "{issue-type} prevention"`
|
|
48
|
+
- 웹 검색: OWASP, ShellCheck wiki, 전문가 가이드
|
|
49
|
+
→ 수정 계획 수립 (리서치 기반)
|
|
50
|
+
→ 수정 적용
|
|
51
|
+
→ 해당 레이어 재검증
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### 수정 패턴 참조
|
|
55
|
+
|
|
56
|
+
`references/security-fix-patterns.md` — 발견 빈도 높은 취약점별 수정 패턴 모음.
|
|
57
|
+
|
|
58
|
+
## Phase 5: 재검증
|
|
59
|
+
|
|
60
|
+
모든 수정 후 전체 레이어 재실행하여 regression 없음을 확인.
|
|
61
|
+
|
|
62
|
+
## 검증 시점
|
|
63
|
+
|
|
64
|
+
| 시점 | 레이어 | 범위 |
|
|
65
|
+
|------|--------|------|
|
|
66
|
+
| 커밋 전 | L0, L1 | 변경 파일 |
|
|
67
|
+
| 스프린트 완료 | L0~L5 | 전체 프로젝트 |
|
|
68
|
+
| 릴리스 전 | L0~L6 | 전체 프로젝트 |
|
|
69
|
+
| 보안 감사 요청 | L2 집중 | 전체 프로젝트 |
|