bigpowers 2.34.1 → 2.35.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/.pi/package.json +2 -2
- package/.pi/prompts/deploy.md +53 -28
- package/.pi/prompts/develop-tdd.md +5 -80
- package/.pi/prompts/migrate-spec.md +273 -197
- package/.pi/prompts/publish-package.md +125 -67
- package/.pi/prompts/release-branch.md +85 -69
- package/.pi/prompts/security-review.md +323 -0
- package/.pi/prompts/smoke-test.md +98 -58
- package/.pi/prompts/using-bigpowers.md +2 -2
- package/.pi/prompts/validate-contracts.md +169 -54
- package/.pi/prompts/wire-ci.md +147 -89
- package/.pi/skills/deploy/SKILL.md +53 -28
- package/.pi/skills/develop-tdd/SKILL.md +5 -80
- package/.pi/skills/migrate-spec/SKILL.md +273 -197
- package/.pi/skills/publish-package/SKILL.md +125 -67
- package/.pi/skills/release-branch/SKILL.md +85 -69
- package/.pi/skills/security-review/SKILL.md +324 -0
- package/.pi/skills/smoke-test/SKILL.md +98 -58
- package/.pi/skills/using-bigpowers/SKILL.md +2 -2
- package/.pi/skills/validate-contracts/SKILL.md +169 -54
- package/.pi/skills/wire-ci/SKILL.md +147 -89
- package/CHANGELOG.md +14 -0
- package/README.md +4 -4
- package/SKILL-INDEX.md +2 -2
- package/deploy/REFERENCE.md +82 -0
- package/deploy/SKILL.md +3 -63
- package/develop-tdd/SKILL.md +5 -80
- package/migrate-spec/REFERENCE.md +268 -0
- package/migrate-spec/SKILL.md +5 -199
- package/package.json +2 -2
- package/publish-package/REFERENCE.md +239 -0
- package/publish-package/SKILL.md +8 -192
- package/release-branch/REFERENCE.md +83 -0
- package/release-branch/SKILL.md +2 -69
- package/scripts/generate-reference-tables.sh +1 -0
- package/scripts/sync-skills.sh +4 -1
- package/security-review/REFERENCE-confidence-rubric.md +85 -0
- package/security-review/REFERENCE-false-positives.md +68 -0
- package/security-review/REFERENCE-vuln-categories.md +103 -0
- package/security-review/SKILL.md +63 -0
- package/skills-lock.json +14 -9
- package/smoke-test/REFERENCE.md +162 -0
- package/smoke-test/SKILL.md +5 -130
- package/using-bigpowers/SKILL.md +2 -2
- package/validate-contracts/REFERENCE.md +183 -0
- package/validate-contracts/SKILL.md +6 -77
- package/wire-ci/REFERENCE.md +257 -0
- package/wire-ci/SKILL.md +8 -210
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
# Vulnerability Categories — Detection Guidance
|
|
2
|
+
|
|
3
|
+
Each category: vulnerable pattern → safe pattern → code example.
|
|
4
|
+
|
|
5
|
+
## SQL Injection
|
|
6
|
+
|
|
7
|
+
| Aspect | Detail |
|
|
8
|
+
|--------|--------|
|
|
9
|
+
| **Vulnerable** | String interpolation in SQL queries: `f"SELECT * FROM users WHERE id = {uid}"` |
|
|
10
|
+
| **Safe** | Parameterized queries / ORM: `cursor.execute("SELECT * FROM users WHERE id = %s", (uid,))` |
|
|
11
|
+
| **Look for** | f-strings, `+` concatenation, `format()` in query builders; raw SQL in ORM `.raw()` / `.execute()` |
|
|
12
|
+
| **False-positive guard** | Not a FP if the input is user-controlled (HTTP param, file, env var, CLI arg). Env vars are trusted (see exclusion rules). |
|
|
13
|
+
|
|
14
|
+
## Cross-Site Scripting (XSS)
|
|
15
|
+
|
|
16
|
+
| Aspect | Detail |
|
|
17
|
+
|--------|--------|
|
|
18
|
+
| **Vulnerable** | `element.innerHTML = userInput`, `dangerouslySetInnerHTML={{__html: userInput}}` |
|
|
19
|
+
| **Safe** | `element.textContent = userInput`, React JSX (auto-escaped), template engines with auto-escaping |
|
|
20
|
+
| **Look for** | `.innerHTML`, `document.write()`, `dangerouslySetInnerHTML`, `v-html` (Vue), `bypassSecurityTrustHtml` (Angular) |
|
|
21
|
+
| **False-positive guard** | React/Angular components without unsafe methods are NOT vulnerable (see exclusion rules). |
|
|
22
|
+
|
|
23
|
+
## Server-Side Request Forgery (SSRF)
|
|
24
|
+
|
|
25
|
+
| Aspect | Detail |
|
|
26
|
+
|--------|--------|
|
|
27
|
+
| **Vulnerable** | User-controlled URL passed to server-side HTTP client: `requests.get(user_url)` |
|
|
28
|
+
| **Safe** | URL allowlist validation, internal-network blocking, protocol/host restriction |
|
|
29
|
+
| **Look for** | User input → `fetch`, `requests.get`, `axios.get`, `urllib`, `curl`, `http.get`; host control only (path-only is excluded) |
|
|
30
|
+
|
|
31
|
+
## Command Injection
|
|
32
|
+
|
|
33
|
+
| Aspect | Detail |
|
|
34
|
+
|--------|--------|
|
|
35
|
+
| **Vulnerable** | User input in shell commands: `os.system(f"ping {host}")`, `subprocess.run(f"grep {pattern} file", shell=True)` |
|
|
36
|
+
| **Safe** | `subprocess.run(["ping", host])` with arguments as list; `shlex.quote()` |
|
|
37
|
+
| **Look for** | `shell=True`, `os.system`, `os.popen`, `exec()`, `eval()`, `$()`, backticks |
|
|
38
|
+
| **False-positive guard** | Shell scripts without untrusted user input are generally not exploitable. |
|
|
39
|
+
|
|
40
|
+
## Authentication/Authorization Bypass
|
|
41
|
+
|
|
42
|
+
| Aspect | Detail |
|
|
43
|
+
|--------|--------|
|
|
44
|
+
| **Vulnerable** | Missing auth check on protected endpoint; JWT without signature verification; hardcoded admin tokens |
|
|
45
|
+
| **Safe** | Consistent auth middleware; JWT with `RS256`/`HS256` verification; role-based access control |
|
|
46
|
+
| **Look for** | Routes without auth decorators; `@login_required` / `@require_auth` missing; JWT without `.verify()`; client-side auth checks only |
|
|
47
|
+
|
|
48
|
+
## Unsafe Deserialization
|
|
49
|
+
|
|
50
|
+
| Aspect | Detail |
|
|
51
|
+
|--------|--------|
|
|
52
|
+
| **Vulnerable** | `pickle.load(user_data)`, `yaml.load(user_input)`, `JSON.parse()` on untrusted tokens, `eval(input())` |
|
|
53
|
+
| **Safe** | `yaml.safe_load()`, `json.loads()` (safe for JSON), `pickle.load(weights_only=True)` (PyTorch), schema validation |
|
|
54
|
+
| **Look for** | `pickle.load`, `yaml.load` (not safe_load), `torch.load(weights_only=False)`, `eval`, `marshal.load`, `node-serialize` |
|
|
55
|
+
|
|
56
|
+
## Path Traversal
|
|
57
|
+
|
|
58
|
+
| Aspect | Detail |
|
|
59
|
+
|--------|--------|
|
|
60
|
+
| **Vulnerable** | User input in file paths: `open(f"/data/{filename}")`, `path.join(base, user_path)` |
|
|
61
|
+
| **Safe** | Path normalization + prefix check: `os.path.realpath(path).startswith(BASE_DIR)`; allowlist of valid filenames |
|
|
62
|
+
| **Look for** | `open()`, `read_file()`, `os.path.join` with user input; `../` traversal without normalization |
|
|
63
|
+
|
|
64
|
+
## Insecure Direct Object Reference (IDOR)
|
|
65
|
+
|
|
66
|
+
| Aspect | Detail |
|
|
67
|
+
|--------|--------|
|
|
68
|
+
| **Vulnerable** | API endpoint uses user-supplied ID without ownership check: `GET /api/order/{order_id}` — returns any user's order |
|
|
69
|
+
| **Safe** | Ownership verification: verify `order.user_id == current_user.id` before returning data |
|
|
70
|
+
| **Look for** | CRUD endpoints that accept IDs without authorization; horizontal/vertical privilege checks missing |
|
|
71
|
+
|
|
72
|
+
## Weak Cryptography
|
|
73
|
+
|
|
74
|
+
| Aspect | Detail |
|
|
75
|
+
|--------|--------|
|
|
76
|
+
| **Vulnerable** | MD5/SHA1 for passwords; ECB mode; hardcoded keys; `random` module (not `secrets`); short key lengths |
|
|
77
|
+
| **Safe** | `bcrypt`/`argon2` for passwords; AES-GCM; `secrets` module; RSA 2048+; proper IV generation |
|
|
78
|
+
| **Look for** | `md5`, `sha1`, `DES`, `ECB`, `PKCS1_v1_5`, `random` for crypto, hardcoded `key=`, `Crypto.Cipher` without AEAD |
|
|
79
|
+
|
|
80
|
+
## Secrets Exposure
|
|
81
|
+
|
|
82
|
+
| Aspect | Detail |
|
|
83
|
+
|--------|--------|
|
|
84
|
+
| **Vulnerable** | Hardcoded API keys, passwords, tokens in source code; secrets in logs; secrets in client-side code |
|
|
85
|
+
| **Safe** | Environment variables; secret manager (AWS Secrets Manager, HashiCorp Vault); `.env` excluded from VCS |
|
|
86
|
+
| **Look for** | `API_KEY=`, `password=`, `secret=`, `token=` in code; AWS keys, GitHub tokens, Stripe keys, JWTs in source |
|
|
87
|
+
| **False-positive guard** | Secrets stored on disk but otherwise secured ARE excluded. Logging high-value secrets IS a vuln. Logging URLs is safe. |
|
|
88
|
+
|
|
89
|
+
## Template Injection (SSTI)
|
|
90
|
+
|
|
91
|
+
| Aspect | Detail |
|
|
92
|
+
|--------|--------|
|
|
93
|
+
| **Vulnerable** | User input in template rendering: `Template(user_input).render()`, `render_template_string(user_input)` |
|
|
94
|
+
| **Safe** | Static templates; input passed as context variable, not template string |
|
|
95
|
+
| **Look for** | `render_template_string`, `Template()()` with user string; `eval` in template context; `${user_input}` in JS template literals on server |
|
|
96
|
+
|
|
97
|
+
## NoSQL Injection
|
|
98
|
+
|
|
99
|
+
| Aspect | Detail |
|
|
100
|
+
|--------|--------|
|
|
101
|
+
| **Vulnerable** | User input in MongoDB queries: `db.users.find({username: user_input})` where input is `{"$gt": ""}` |
|
|
102
|
+
| **Safe** | Schema validation; type checking on query params; ORM sanitization |
|
|
103
|
+
| **Look for** | MongoDB `$where`, `$gt`, `$regex` from user input; raw mongo queries without type coercion |
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: security-review
|
|
3
|
+
description: >
|
|
4
|
+
AI-powered security analysis of code changes — traces data flow, detects
|
|
5
|
+
injection, auth bypass, secrets exposure, and unsafe deserialization across
|
|
6
|
+
files. Use when reviewing pending changes, before release-branch, during
|
|
7
|
+
verify-work Phase 5, during build-epic Step 0 threat modeling, or when
|
|
8
|
+
the user says "security review" or "scan for vulns".
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Security Review
|
|
12
|
+
|
|
13
|
+
> **HARD GATE** — Requires git context (branch with merge-base or diff). Never
|
|
14
|
+
> writes files outside `specs/security/`. Findings below confidence 8/10 are
|
|
15
|
+
> suppressed. **→ verify:** `git rev-parse HEAD >/dev/null 2>&1 && echo "ok" || echo "BLOCKED"`
|
|
16
|
+
|
|
17
|
+
## 5-phase scan
|
|
18
|
+
|
|
19
|
+
| # | Phase | What |
|
|
20
|
+
|---|-------|------|
|
|
21
|
+
| 1 | **Scope Resolution** | Detect diff via `git diff --merge-base origin/HEAD`; resolve languages/frameworks from dependency files |
|
|
22
|
+
| 2 | **Context Research** | Identify existing security patterns, sanitization, auth model in the codebase |
|
|
23
|
+
| 3 | **Vulnerability Assessment** | Trace user input → sink; check auth boundaries, crypto, deserialization, path ops |
|
|
24
|
+
| 4 | **False-Positive Filtering** | Cross-check each finding against exclusion rules; reject confidence < 8 |
|
|
25
|
+
| 5 | **Report Generation** | Output structured markdown: file:line, severity, category, exploit scenario, fix |
|
|
26
|
+
|
|
27
|
+
## Categories
|
|
28
|
+
|
|
29
|
+
Covered: SQLi, XSS, SSRF, command injection, auth bypass, unsafe deserialization, path traversal, IDOR, crypto flaws, secrets exposure, template injection, NoSQLi
|
|
30
|
+
|
|
31
|
+
## Integration points
|
|
32
|
+
|
|
33
|
+
| Skill | Touchpoint |
|
|
34
|
+
|-------|------------|
|
|
35
|
+
| `build-epic` | Step 0 — threat-model epic scope → `specs/security/epics/<id>/THREAT_MODEL.md` |
|
|
36
|
+
| `plan-work` | `security:` field (none/low/medium/high) on story tasks |
|
|
37
|
+
| `plan-release` | +2 WSJF risk boost for HIGH+ risk epics |
|
|
38
|
+
| `audit-code` | Checklist: "diff scanned — no unaddressed HIGH findings" |
|
|
39
|
+
| `request-review` | Inject threat model categories + false-positive rules into reviewer prompt |
|
|
40
|
+
| `investigate-bug` | Security-impact assessment in RCA (NONE→CRITICAL) |
|
|
41
|
+
| `validate-fix` | Recurrence hardening check for security bugs |
|
|
42
|
+
| `verify-work` | Phase 5 — blocks on HIGH findings ≥ 8 confidence |
|
|
43
|
+
| `release-branch` | Hard gate — blocks merge if unresolved HIGH findings |
|
|
44
|
+
|
|
45
|
+
## Report format
|
|
46
|
+
|
|
47
|
+
Each finding: **`File:Line` — Severity — Category**
|
|
48
|
+
- Description: how the vulnerability manifests
|
|
49
|
+
- Exploit scenario: concrete attack path
|
|
50
|
+
- Recommendation: fix with code example
|
|
51
|
+
|
|
52
|
+
## Reference files
|
|
53
|
+
|
|
54
|
+
- [Vuln categories](REFERENCE-vuln-categories.md) — detection guidance per vuln type
|
|
55
|
+
- [False positives](REFERENCE-false-positives.md) — hard exclusions + precedent
|
|
56
|
+
- [Confidence rubric](REFERENCE-confidence-rubric.md) — scoring methodology (0–10)
|
|
57
|
+
|
|
58
|
+
## Verify
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
test -d specs/security && echo "OK: specs/security/ exists" || mkdir -p specs/security
|
|
62
|
+
grep -q "Merge-base\|merge.base\|git diff" SKILL.md && echo "OK: git context verified"
|
|
63
|
+
```
|
package/skills-lock.json
CHANGED
|
@@ -68,7 +68,7 @@
|
|
|
68
68
|
},
|
|
69
69
|
"deploy": {
|
|
70
70
|
"description": "\"Build → verify artifact → deploy → wait → smoke deployment pipeline. Platform-agnostic (MCP or CLI), with configurable timeout, retry with exponential backoff, and integrated health-check. The deploy half of CI/CD: run after build to push to production.\"",
|
|
71
|
-
"sha256": "
|
|
71
|
+
"sha256": "304967c4f7d0ea13",
|
|
72
72
|
"path": "deploy/SKILL.md"
|
|
73
73
|
},
|
|
74
74
|
"design-interface": {
|
|
@@ -78,7 +78,7 @@
|
|
|
78
78
|
},
|
|
79
79
|
"develop-tdd": {
|
|
80
80
|
"description": "Test-driven development with red-green-refactor loop using vertical slices. Use for features (epic tasks) or bugs (specs/bugs/BUG-*.md).",
|
|
81
|
-
"sha256": "
|
|
81
|
+
"sha256": "8a232210dc2c11d3",
|
|
82
82
|
"path": "develop-tdd/SKILL.md"
|
|
83
83
|
},
|
|
84
84
|
"diagnose-root": {
|
|
@@ -163,7 +163,7 @@
|
|
|
163
163
|
},
|
|
164
164
|
"migrate-spec": {
|
|
165
165
|
"description": "Detect GSD, spec-kit, or BMAD spec artifacts and transform them into bigpowers YAML layout (state.yaml, release-plan.yaml, epics/, requirements/, plans/, ADRs). Use when migrating foreign spec docs.",
|
|
166
|
-
"sha256": "
|
|
166
|
+
"sha256": "84077c1eaa2ec40d",
|
|
167
167
|
"path": "migrate-spec/SKILL.md"
|
|
168
168
|
},
|
|
169
169
|
"model-domain": {
|
|
@@ -198,7 +198,7 @@
|
|
|
198
198
|
},
|
|
199
199
|
"publish-package": {
|
|
200
200
|
"description": "\"Package registry publishing for npm, crates.io, PyPI, and Homebrew. Verifies prerequisites, runs the publish command, confirms success, and surfaces actionable error hints on failure.\"",
|
|
201
|
-
"sha256": "
|
|
201
|
+
"sha256": "39f5ba9b115cca6b",
|
|
202
202
|
"path": "publish-package/SKILL.md"
|
|
203
203
|
},
|
|
204
204
|
"quick-fix": {
|
|
@@ -208,7 +208,7 @@
|
|
|
208
208
|
},
|
|
209
209
|
"release-branch": {
|
|
210
210
|
"description": "Make the merge/PR/keep/discard decision for a feature branch, verify coverage gates, create the PR with gh, and clean up the worktree. Use when a feature is done and ready to ship, or when user says \"release\", \"merge\", or \"open a PR\".",
|
|
211
|
-
"sha256": "
|
|
211
|
+
"sha256": "fd5e968246ce07bd",
|
|
212
212
|
"path": "release-branch/SKILL.md"
|
|
213
213
|
},
|
|
214
214
|
"request-review": {
|
|
@@ -256,6 +256,11 @@
|
|
|
256
256
|
"sha256": "34df830694a6459c",
|
|
257
257
|
"path": "search-skills/SKILL.md"
|
|
258
258
|
},
|
|
259
|
+
"security-review": {
|
|
260
|
+
"description": "> AI-powered security analysis of code changes — traces data flow, detects injection, auth bypass, secrets exposure, and unsafe deserialization across files. Use when reviewing pending changes, before release-branch, during verify-work Phase 5, during build-epic Step 0 threat modeling, or when the user says \"security review\" or \"scan for vulns\".",
|
|
261
|
+
"sha256": "24aeeed072282d0c",
|
|
262
|
+
"path": "security-review/SKILL.md"
|
|
263
|
+
},
|
|
259
264
|
"seed-conventions": {
|
|
260
265
|
"description": "Generate CLAUDE.md and CONVENTIONS.md for a brand-new project through a brief interview, and create the specs/ directory with evolved bigpowers structure (product/, tech-architecture/, verifications/, epics/archive/). Entry point for greenfield projects. Use when starting a new project from scratch, when user asks to set up AI agent conventions, or when there is no CLAUDE.md yet.",
|
|
261
266
|
"sha256": "cd3a7fc52d1b0035",
|
|
@@ -283,7 +288,7 @@
|
|
|
283
288
|
},
|
|
284
289
|
"smoke-test": {
|
|
285
290
|
"description": "\"Post-deploy health-check against a live URL. Validates HTTP status, response content, and critical endpoints. Runnable standalone OR as the final step of the deploy skill.\"",
|
|
286
|
-
"sha256": "
|
|
291
|
+
"sha256": "85d2de9e87e141f7",
|
|
287
292
|
"path": "smoke-test/SKILL.md"
|
|
288
293
|
},
|
|
289
294
|
"spike-prototype": {
|
|
@@ -313,12 +318,12 @@
|
|
|
313
318
|
},
|
|
314
319
|
"using-bigpowers": {
|
|
315
320
|
"description": "One-time bootstrap that introduces the bigpowers skills system, the PMBOK lifecycle arc, and tells you which skill to call first for your situation. Use when starting with bigpowers for the first time, when user asks \"where do I start?\", or when the skills system needs to be explained.",
|
|
316
|
-
"sha256": "
|
|
321
|
+
"sha256": "3e73bdd359b49743",
|
|
317
322
|
"path": "using-bigpowers/SKILL.md"
|
|
318
323
|
},
|
|
319
324
|
"validate-contracts": {
|
|
320
325
|
"description": "\"Assert data shape consistency across system boundaries — live API responses against JSON Schema, key-set comparison across layers, data shape validation for migrations and exports. Catches silent data corruption before deploy.\"",
|
|
321
|
-
"sha256": "
|
|
326
|
+
"sha256": "59cf618f642fa10c",
|
|
322
327
|
"path": "validate-contracts/SKILL.md"
|
|
323
328
|
},
|
|
324
329
|
"validate-fix": {
|
|
@@ -338,7 +343,7 @@
|
|
|
338
343
|
},
|
|
339
344
|
"wire-ci": {
|
|
340
345
|
"description": "\"CI pipeline setup with pre-built templates and local validation. Generates GitHub Actions workflows, validates YAML syntax and permissions, supports dry-run via act/gh. The CI equivalent of wire-observability.\"",
|
|
341
|
-
"sha256": "
|
|
346
|
+
"sha256": "cc3fd8faf2686be1",
|
|
342
347
|
"path": "wire-ci/SKILL.md"
|
|
343
348
|
},
|
|
344
349
|
"wire-observability": {
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
# Smoke Test — Reference
|
|
2
|
+
|
|
3
|
+
## Runner script
|
|
4
|
+
|
|
5
|
+
A ready-to-use runner is provided for standalone operation:
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
bash scripts/run-smoke.sh [url] [smoke-checks-file]
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
The runner:
|
|
12
|
+
1. Uses `$DEPLOY_URL`, `$SMOKE_CHECKS_FILE`, or CLI arguments
|
|
13
|
+
2. Runs all defined checks
|
|
14
|
+
3. Prints a pass/fail summary
|
|
15
|
+
4. Exits 0 on all pass, non-zero on any failure
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## Configuration reference
|
|
21
|
+
|
|
22
|
+
| Variable | Default | Description |
|
|
23
|
+
|----------|---------|-------------|
|
|
24
|
+
| `SMOKE_CHECKS_FILE` | `smoke-checks.yaml` | Path to smoke checks YAML |
|
|
25
|
+
| `DEPLOY_URL` / `BASE_URL` | *(required)* | Base URL for all checks |
|
|
26
|
+
| `SMOKE_TIMEOUT` | `30` | Per-check timeout (seconds) |
|
|
27
|
+
| `SMOKE_RETRIES` | `0` | Number of retries on failure |
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## Verification
|
|
33
|
+
|
|
34
|
+
→ verify: `test -f smoke-test/SKILL.md && grep -q 'name: smoke-test' smoke-test/SKILL.md && echo OK`
|
|
35
|
+
→ verify: `grep -qi 'smoke.checks.yaml\|checklist\|expected_status\|content_signal' smoke-test/SKILL.md && echo OK`
|
|
36
|
+
→ verify: `grep -ci 'pass\|fail\|summary\|report' smoke-test/SKILL.md | awk '{if($1>=2) print "OK"; else print "FAIL"}'`
|
|
37
|
+
→ verify: `grep -q 'smoke-test' SKILL-INDEX.md && echo OK`
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## Reference block 1
|
|
42
|
+
|
|
43
|
+
```yaml
|
|
44
|
+
# smoke-checks.yaml — auto-loaded if present at project root
|
|
45
|
+
base_url: "https://example.com"
|
|
46
|
+
checks:
|
|
47
|
+
- name: "Homepage"
|
|
48
|
+
path: "/"
|
|
49
|
+
method: GET
|
|
50
|
+
expected_status: 200
|
|
51
|
+
content_signal: "bigpowers"
|
|
52
|
+
max_response_time_ms: 3000
|
|
53
|
+
|
|
54
|
+
- name: "API Health"
|
|
55
|
+
path: "/api/health"
|
|
56
|
+
method: GET
|
|
57
|
+
expected_status: 200
|
|
58
|
+
content_signal: "ok|healthy"
|
|
59
|
+
|
|
60
|
+
- name: "API Jogos"
|
|
61
|
+
path: "/api/jogos"
|
|
62
|
+
method: GET
|
|
63
|
+
expected_status: 200
|
|
64
|
+
content_signal: "jogos|games"
|
|
65
|
+
|
|
66
|
+
- name: "Not Found handling"
|
|
67
|
+
path: "/nonexistent"
|
|
68
|
+
method: GET
|
|
69
|
+
expected_status: 404
|
|
70
|
+
content_signal: "not found|404"
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
## Reference block 2
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
SMOKE_CHECKS_FILE="${SMOKE_CHECKS_FILE:-smoke-checks.yaml}"
|
|
79
|
+
BASE_URL="${DEPLOY_URL:-$BASE_URL}"
|
|
80
|
+
|
|
81
|
+
if [ -f "$SMOKE_CHECKS_FILE" ]; then
|
|
82
|
+
echo "Loaded smoke checks from $SMOKE_CHECKS_FILE"
|
|
83
|
+
elif [ -n "$BASE_URL" ]; then
|
|
84
|
+
echo "No smoke-checks.yaml found. Using single URL check against $BASE_URL"
|
|
85
|
+
else
|
|
86
|
+
echo "ERROR: No smoke-checks.yaml found and no DEPLOY_URL/BASE_URL set."
|
|
87
|
+
exit 1
|
|
88
|
+
fi
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
## Reference block 3
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
url="${BASE_URL}${path}"
|
|
97
|
+
start_time=$(python3 -c 'import time; print(int(time.time() * 1000))')
|
|
98
|
+
|
|
99
|
+
# Perform the HTTP request
|
|
100
|
+
response=$(curl -s -o /tmp/smoke_body.txt -w "%{http_code}" "$url")
|
|
101
|
+
response_time=$(( $(python3 -c 'import time; print(int(time.time() * 1000))') - start_time ))
|
|
102
|
+
status=$response
|
|
103
|
+
body=$(cat /tmp/smoke_body.txt)
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
---
|
|
107
|
+
|
|
108
|
+
## Reference block 4
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
checks_passed=0
|
|
112
|
+
checks_failed=0
|
|
113
|
+
failures=""
|
|
114
|
+
|
|
115
|
+
# Assert status code
|
|
116
|
+
if [ "$status" -ne "${expected_status:-200}" ]; then
|
|
117
|
+
echo " FAIL: expected status ${expected_status} but got $status"
|
|
118
|
+
checks_failed=$((checks_failed + 1))
|
|
119
|
+
failures="${failures} - $name: HTTP $status (expected ${expected_status})\n"
|
|
120
|
+
else
|
|
121
|
+
echo " PASS: HTTP $status"
|
|
122
|
+
fi
|
|
123
|
+
|
|
124
|
+
# Assert content signal
|
|
125
|
+
if [ -n "$content_signal" ]; then
|
|
126
|
+
if echo "$body" | grep -qiE "$content_signal"; then
|
|
127
|
+
echo " PASS: body contains \"$content_signal\""
|
|
128
|
+
else
|
|
129
|
+
echo " FAIL: body does not contain \"$content_signal\""
|
|
130
|
+
checks_failed=$((checks_failed + 1))
|
|
131
|
+
failures="${failures} - $name: missing content signal \"$content_signal\"\n"
|
|
132
|
+
fi
|
|
133
|
+
fi
|
|
134
|
+
|
|
135
|
+
# Assert response time
|
|
136
|
+
if [ -n "$max_response_time_ms" ] && [ "$response_time" -gt "$max_response_time_ms" ]; then
|
|
137
|
+
echo " FAIL: response time ${response_time}ms exceeds ${max_response_time_ms}ms"
|
|
138
|
+
checks_failed=$((checks_failed + 1))
|
|
139
|
+
failures="${failures} - $name: response time ${response_time}ms (max ${max_response_time_ms}ms)\n"
|
|
140
|
+
fi
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
## Reference block 5
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
total=$((checks_passed + checks_failed))
|
|
149
|
+
echo ""
|
|
150
|
+
echo "=== Smoke Test Summary ==="
|
|
151
|
+
echo "Total: $total | Passed: $checks_passed | Failed: $checks_failed"
|
|
152
|
+
|
|
153
|
+
if [ "$checks_failed" -gt 0 ]; then
|
|
154
|
+
echo ""
|
|
155
|
+
echo "Failures:"
|
|
156
|
+
echo -e "$failures"
|
|
157
|
+
exit 1
|
|
158
|
+
else
|
|
159
|
+
echo "All checks passed."
|
|
160
|
+
exit 0
|
|
161
|
+
fi
|
|
162
|
+
```
|
package/smoke-test/SKILL.md
CHANGED
|
@@ -21,35 +21,7 @@ Can be run standalone for quick health checks or chained as the final step of th
|
|
|
21
21
|
|
|
22
22
|
Smoke checks are defined in `smoke-checks.yaml` at the project root:
|
|
23
23
|
|
|
24
|
-
|
|
25
|
-
# smoke-checks.yaml — auto-loaded if present at project root
|
|
26
|
-
base_url: "https://example.com"
|
|
27
|
-
checks:
|
|
28
|
-
- name: "Homepage"
|
|
29
|
-
path: "/"
|
|
30
|
-
method: GET
|
|
31
|
-
expected_status: 200
|
|
32
|
-
content_signal: "bigpowers"
|
|
33
|
-
max_response_time_ms: 3000
|
|
34
|
-
|
|
35
|
-
- name: "API Health"
|
|
36
|
-
path: "/api/health"
|
|
37
|
-
method: GET
|
|
38
|
-
expected_status: 200
|
|
39
|
-
content_signal: "ok|healthy"
|
|
40
|
-
|
|
41
|
-
- name: "API Jogos"
|
|
42
|
-
path: "/api/jogos"
|
|
43
|
-
method: GET
|
|
44
|
-
expected_status: 200
|
|
45
|
-
content_signal: "jogos|games"
|
|
46
|
-
|
|
47
|
-
- name: "Not Found handling"
|
|
48
|
-
path: "/nonexistent"
|
|
49
|
-
method: GET
|
|
50
|
-
expected_status: 404
|
|
51
|
-
content_signal: "not found|404"
|
|
52
|
-
```
|
|
24
|
+
See [REFERENCE.md](REFERENCE.md)
|
|
53
25
|
|
|
54
26
|
Checks can also be specified inline via environment variables or CLI arguments for ad-hoc use.
|
|
55
27
|
|
|
@@ -68,102 +40,21 @@ Checks can also be specified inline via environment variables or CLI arguments f
|
|
|
68
40
|
|
|
69
41
|
### 1. Load smoke checks
|
|
70
42
|
|
|
71
|
-
|
|
72
|
-
SMOKE_CHECKS_FILE="${SMOKE_CHECKS_FILE:-smoke-checks.yaml}"
|
|
73
|
-
BASE_URL="${DEPLOY_URL:-$BASE_URL}"
|
|
74
|
-
|
|
75
|
-
if [ -f "$SMOKE_CHECKS_FILE" ]; then
|
|
76
|
-
echo "Loaded smoke checks from $SMOKE_CHECKS_FILE"
|
|
77
|
-
elif [ -n "$BASE_URL" ]; then
|
|
78
|
-
echo "No smoke-checks.yaml found. Using single URL check against $BASE_URL"
|
|
79
|
-
else
|
|
80
|
-
echo "ERROR: No smoke-checks.yaml found and no DEPLOY_URL/BASE_URL set."
|
|
81
|
-
exit 1
|
|
82
|
-
fi
|
|
83
|
-
```
|
|
43
|
+
See [REFERENCE.md](REFERENCE.md)
|
|
84
44
|
|
|
85
45
|
### 2. Run each check
|
|
86
46
|
|
|
87
47
|
For each check in the configuration, perform an HTTP request:
|
|
88
48
|
|
|
89
|
-
|
|
90
|
-
url="${BASE_URL}${path}"
|
|
91
|
-
start_time=$(python3 -c 'import time; print(int(time.time() * 1000))')
|
|
92
|
-
|
|
93
|
-
# Perform the HTTP request
|
|
94
|
-
response=$(curl -s -o /tmp/smoke_body.txt -w "%{http_code}" "$url")
|
|
95
|
-
response_time=$(( $(python3 -c 'import time; print(int(time.time() * 1000))') - start_time ))
|
|
96
|
-
status=$response
|
|
97
|
-
body=$(cat /tmp/smoke_body.txt)
|
|
98
|
-
```
|
|
49
|
+
See [REFERENCE.md](REFERENCE.md)
|
|
99
50
|
|
|
100
51
|
### 3. Assert results
|
|
101
52
|
|
|
102
|
-
|
|
103
|
-
checks_passed=0
|
|
104
|
-
checks_failed=0
|
|
105
|
-
failures=""
|
|
106
|
-
|
|
107
|
-
# Assert status code
|
|
108
|
-
if [ "$status" -ne "${expected_status:-200}" ]; then
|
|
109
|
-
echo " FAIL: expected status ${expected_status} but got $status"
|
|
110
|
-
checks_failed=$((checks_failed + 1))
|
|
111
|
-
failures="${failures} - $name: HTTP $status (expected ${expected_status})\n"
|
|
112
|
-
else
|
|
113
|
-
echo " PASS: HTTP $status"
|
|
114
|
-
fi
|
|
115
|
-
|
|
116
|
-
# Assert content signal
|
|
117
|
-
if [ -n "$content_signal" ]; then
|
|
118
|
-
if echo "$body" | grep -qiE "$content_signal"; then
|
|
119
|
-
echo " PASS: body contains \"$content_signal\""
|
|
120
|
-
else
|
|
121
|
-
echo " FAIL: body does not contain \"$content_signal\""
|
|
122
|
-
checks_failed=$((checks_failed + 1))
|
|
123
|
-
failures="${failures} - $name: missing content signal \"$content_signal\"\n"
|
|
124
|
-
fi
|
|
125
|
-
fi
|
|
126
|
-
|
|
127
|
-
# Assert response time
|
|
128
|
-
if [ -n "$max_response_time_ms" ] && [ "$response_time" -gt "$max_response_time_ms" ]; then
|
|
129
|
-
echo " FAIL: response time ${response_time}ms exceeds ${max_response_time_ms}ms"
|
|
130
|
-
checks_failed=$((checks_failed + 1))
|
|
131
|
-
failures="${failures} - $name: response time ${response_time}ms (max ${max_response_time_ms}ms)\n"
|
|
132
|
-
fi
|
|
133
|
-
```
|
|
53
|
+
See [REFERENCE.md](REFERENCE.md)
|
|
134
54
|
|
|
135
55
|
### 4. Generate report
|
|
136
56
|
|
|
137
|
-
|
|
138
|
-
total=$((checks_passed + checks_failed))
|
|
139
|
-
echo ""
|
|
140
|
-
echo "=== Smoke Test Summary ==="
|
|
141
|
-
echo "Total: $total | Passed: $checks_passed | Failed: $checks_failed"
|
|
142
|
-
|
|
143
|
-
if [ "$checks_failed" -gt 0 ]; then
|
|
144
|
-
echo ""
|
|
145
|
-
echo "Failures:"
|
|
146
|
-
echo -e "$failures"
|
|
147
|
-
exit 1
|
|
148
|
-
else
|
|
149
|
-
echo "All checks passed."
|
|
150
|
-
exit 0
|
|
151
|
-
fi
|
|
152
|
-
```
|
|
153
|
-
|
|
154
|
-
## Runner script
|
|
155
|
-
|
|
156
|
-
A ready-to-use runner is provided for standalone operation:
|
|
157
|
-
|
|
158
|
-
```bash
|
|
159
|
-
bash scripts/run-smoke.sh [url] [smoke-checks-file]
|
|
160
|
-
```
|
|
161
|
-
|
|
162
|
-
The runner:
|
|
163
|
-
1. Uses `$DEPLOY_URL`, `$SMOKE_CHECKS_FILE`, or CLI arguments
|
|
164
|
-
2. Runs all defined checks
|
|
165
|
-
3. Prints a pass/fail summary
|
|
166
|
-
4. Exits 0 on all pass, non-zero on any failure
|
|
57
|
+
See [REFERENCE.md](REFERENCE.md)
|
|
167
58
|
|
|
168
59
|
## Integration with deploy skill
|
|
169
60
|
|
|
@@ -173,19 +64,3 @@ The `deploy` skill references `smoke-test` as its final verification step:
|
|
|
173
64
|
# In deploy workflow — after successful deploy
|
|
174
65
|
DEPLOY_URL="$DEPLOY_URL" bash scripts/run-smoke.sh
|
|
175
66
|
```
|
|
176
|
-
|
|
177
|
-
## Configuration reference
|
|
178
|
-
|
|
179
|
-
| Variable | Default | Description |
|
|
180
|
-
|----------|---------|-------------|
|
|
181
|
-
| `SMOKE_CHECKS_FILE` | `smoke-checks.yaml` | Path to smoke checks YAML |
|
|
182
|
-
| `DEPLOY_URL` / `BASE_URL` | *(required)* | Base URL for all checks |
|
|
183
|
-
| `SMOKE_TIMEOUT` | `30` | Per-check timeout (seconds) |
|
|
184
|
-
| `SMOKE_RETRIES` | `0` | Number of retries on failure |
|
|
185
|
-
|
|
186
|
-
## Verification
|
|
187
|
-
|
|
188
|
-
→ verify: `test -f smoke-test/SKILL.md && grep -q 'name: smoke-test' smoke-test/SKILL.md && echo OK`
|
|
189
|
-
→ verify: `grep -qi 'smoke.checks.yaml\|checklist\|expected_status\|content_signal' smoke-test/SKILL.md && echo OK`
|
|
190
|
-
→ verify: `grep -ci 'pass\|fail\|summary\|report' smoke-test/SKILL.md | awk '{if($1>=2) print "OK"; else print "FAIL"}'`
|
|
191
|
-
→ verify: `grep -q 'smoke-test' SKILL-INDEX.md && echo OK`
|
package/using-bigpowers/SKILL.md
CHANGED
|
@@ -8,7 +8,7 @@ description: One-time bootstrap that introduces the bigpowers skills system, the
|
|
|
8
8
|
> **HARD GATE** — **HARD GATE** — This skill is the entry point. Do NOT skip it when onboarding new users or starting a new session. It establishes the bigpowers methodology, lifecycle phases, and conventions.
|
|
9
9
|
|
|
10
10
|
|
|
11
|
-
Welcome to **bigpowers** — a lifecycle of **
|
|
11
|
+
Welcome to **bigpowers** — a lifecycle of **70** agent skills for production-ready, TDD-driven software by solo developers.
|
|
12
12
|
|
|
13
13
|
## Install
|
|
14
14
|
|
|
@@ -99,7 +99,7 @@ Start the HTTP dashboard with `visual-dashboard` → `GET /api/status?projectDir
|
|
|
99
99
|
- **Integrate:** team default is `gh pr` (team-pr); solo profile uses `land-branch.sh`. Never create GitHub issues from skills — use local Markdown files instead.
|
|
100
100
|
- **One skill, one thing.** If you're unsure which skill to call, call `survey-context` — it reads your current state and recommends the next step.
|
|
101
101
|
- **verify: every step.** Every epic task must have `verify: <runnable command>`. Evidence over claims.
|
|
102
|
-
- **
|
|
102
|
+
- **70 skills.** See `SKILL-INDEX.md`; find skills with `search-skills`.
|
|
103
103
|
|
|
104
104
|
## After this
|
|
105
105
|
|