bigpowers 2.86.4 → 2.86.5
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/.agents/skills/craft-skill/SKILL.md +2 -2
- package/.agents/skills/define-success/SKILL.md +6 -59
- package/.agents/skills/deploy/SKILL.md +1 -1
- package/.agents/skills/elaborate-spec/SKILL.md +1 -1
- package/.agents/skills/harden-vps/SKILL.md +63 -60
- package/.agents/skills/investigate-bug/SKILL.md +2 -2
- package/.agents/skills/orchestrate-project/SKILL.md +1 -1
- package/.agents/skills/plan-refactor/SKILL.md +2 -2
- package/.agents/skills/plan-release/SKILL.md +2 -2
- package/.agents/skills/plan-work/SKILL.md +1 -1
- package/.agents/skills/using-bigpowers/SKILL.md +2 -2
- package/.agents/skills/wire-ci/SKILL.md +11 -14
- package/.codebuddy/skills/craft-skill/SKILL.md +2 -2
- package/.codebuddy/skills/define-success/SKILL.md +6 -59
- package/.codebuddy/skills/deploy/SKILL.md +1 -1
- package/.codebuddy/skills/elaborate-spec/SKILL.md +1 -1
- package/.codebuddy/skills/harden-vps/SKILL.md +63 -60
- package/.codebuddy/skills/investigate-bug/SKILL.md +2 -2
- package/.codebuddy/skills/orchestrate-project/SKILL.md +1 -1
- package/.codebuddy/skills/plan-refactor/SKILL.md +2 -2
- package/.codebuddy/skills/plan-release/SKILL.md +2 -2
- package/.codebuddy/skills/plan-work/SKILL.md +1 -1
- package/.codebuddy/skills/using-bigpowers/SKILL.md +2 -2
- package/.codebuddy/skills/wire-ci/SKILL.md +11 -14
- package/.codex/skills/craft-skill/SKILL.md +2 -2
- package/.codex/skills/define-success/SKILL.md +6 -59
- package/.codex/skills/deploy/SKILL.md +1 -1
- package/.codex/skills/elaborate-spec/SKILL.md +1 -1
- package/.codex/skills/harden-vps/SKILL.md +63 -60
- package/.codex/skills/investigate-bug/SKILL.md +2 -2
- package/.codex/skills/orchestrate-project/SKILL.md +1 -1
- package/.codex/skills/plan-refactor/SKILL.md +2 -2
- package/.codex/skills/plan-release/SKILL.md +2 -2
- package/.codex/skills/plan-work/SKILL.md +1 -1
- package/.codex/skills/using-bigpowers/SKILL.md +2 -2
- package/.codex/skills/wire-ci/SKILL.md +11 -14
- package/.hermes/skills/craft-skill/SKILL.md +2 -2
- package/.hermes/skills/define-success/SKILL.md +6 -59
- package/.hermes/skills/deploy/SKILL.md +1 -1
- package/.hermes/skills/elaborate-spec/SKILL.md +1 -1
- package/.hermes/skills/harden-vps/SKILL.md +63 -60
- package/.hermes/skills/investigate-bug/SKILL.md +2 -2
- package/.hermes/skills/orchestrate-project/SKILL.md +1 -1
- package/.hermes/skills/plan-refactor/SKILL.md +2 -2
- package/.hermes/skills/plan-release/SKILL.md +2 -2
- package/.hermes/skills/plan-work/SKILL.md +1 -1
- package/.hermes/skills/using-bigpowers/SKILL.md +2 -2
- package/.hermes/skills/wire-ci/SKILL.md +11 -14
- package/.kilocode/rules/craft-skill.md +2 -2
- package/.kilocode/rules/define-success.md +6 -59
- package/.kilocode/rules/deploy.md +1 -1
- package/.kilocode/rules/elaborate-spec.md +1 -1
- package/.kilocode/rules/harden-vps.md +63 -60
- package/.kilocode/rules/investigate-bug.md +2 -2
- package/.kilocode/rules/orchestrate-project.md +1 -1
- package/.kilocode/rules/plan-refactor.md +2 -2
- package/.kilocode/rules/plan-release.md +2 -2
- package/.kilocode/rules/plan-work.md +1 -1
- package/.kilocode/rules/using-bigpowers.md +2 -2
- package/.kilocode/rules/wire-ci.md +11 -14
- package/.mimocode/skills/craft-skill/SKILL.md +2 -2
- package/.mimocode/skills/define-success/SKILL.md +6 -59
- package/.mimocode/skills/deploy/SKILL.md +1 -1
- package/.mimocode/skills/elaborate-spec/SKILL.md +1 -1
- package/.mimocode/skills/harden-vps/SKILL.md +63 -60
- package/.mimocode/skills/investigate-bug/SKILL.md +2 -2
- package/.mimocode/skills/orchestrate-project/SKILL.md +1 -1
- package/.mimocode/skills/plan-refactor/SKILL.md +2 -2
- package/.mimocode/skills/plan-release/SKILL.md +2 -2
- package/.mimocode/skills/plan-work/SKILL.md +1 -1
- package/.mimocode/skills/using-bigpowers/SKILL.md +2 -2
- package/.mimocode/skills/wire-ci/SKILL.md +11 -14
- package/.pi/package.json +1 -1
- package/.pi/prompts/craft-skill.md +2 -2
- package/.pi/prompts/define-success.md +5 -58
- package/.pi/prompts/deploy.md +1 -1
- package/.pi/prompts/elaborate-spec.md +1 -1
- package/.pi/prompts/harden-vps.md +63 -60
- package/.pi/prompts/investigate-bug.md +2 -2
- package/.pi/prompts/orchestrate-project.md +1 -1
- package/.pi/prompts/plan-refactor.md +2 -2
- package/.pi/prompts/plan-release.md +2 -2
- package/.pi/prompts/plan-work.md +1 -1
- package/.pi/prompts/using-bigpowers.md +2 -2
- package/.pi/prompts/wire-ci.md +11 -14
- package/.pi/skills/craft-skill/SKILL.md +2 -2
- package/.pi/skills/define-success/SKILL.md +6 -59
- package/.pi/skills/deploy/SKILL.md +1 -1
- package/.pi/skills/elaborate-spec/SKILL.md +1 -1
- package/.pi/skills/harden-vps/SKILL.md +63 -60
- package/.pi/skills/investigate-bug/SKILL.md +2 -2
- package/.pi/skills/orchestrate-project/SKILL.md +1 -1
- package/.pi/skills/plan-refactor/SKILL.md +2 -2
- package/.pi/skills/plan-release/SKILL.md +2 -2
- package/.pi/skills/plan-work/SKILL.md +1 -1
- package/.pi/skills/using-bigpowers/SKILL.md +2 -2
- package/.pi/skills/wire-ci/SKILL.md +11 -14
- package/.trae/skills/craft-skill/SKILL.md +2 -2
- package/.trae/skills/define-success/SKILL.md +6 -59
- package/.trae/skills/deploy/SKILL.md +1 -1
- package/.trae/skills/elaborate-spec/SKILL.md +1 -1
- package/.trae/skills/harden-vps/SKILL.md +63 -60
- package/.trae/skills/investigate-bug/SKILL.md +2 -2
- package/.trae/skills/orchestrate-project/SKILL.md +1 -1
- package/.trae/skills/plan-refactor/SKILL.md +2 -2
- package/.trae/skills/plan-release/SKILL.md +2 -2
- package/.trae/skills/plan-work/SKILL.md +1 -1
- package/.trae/skills/using-bigpowers/SKILL.md +2 -2
- package/.trae/skills/wire-ci/SKILL.md +11 -14
- package/.windsurf/rules/craft-skill.md +2 -2
- package/.windsurf/rules/define-success.md +6 -59
- package/.windsurf/rules/deploy.md +1 -1
- package/.windsurf/rules/elaborate-spec.md +1 -1
- package/.windsurf/rules/harden-vps.md +63 -60
- package/.windsurf/rules/investigate-bug.md +2 -2
- package/.windsurf/rules/orchestrate-project.md +1 -1
- package/.windsurf/rules/plan-refactor.md +2 -2
- package/.windsurf/rules/plan-release.md +2 -2
- package/.windsurf/rules/plan-work.md +1 -1
- package/.windsurf/rules/using-bigpowers.md +2 -2
- package/.windsurf/rules/wire-ci.md +11 -14
- package/.zcode/skills/craft-skill/SKILL.md +2 -2
- package/.zcode/skills/define-success/SKILL.md +6 -59
- package/.zcode/skills/deploy/SKILL.md +1 -1
- package/.zcode/skills/elaborate-spec/SKILL.md +1 -1
- package/.zcode/skills/harden-vps/SKILL.md +63 -60
- package/.zcode/skills/investigate-bug/SKILL.md +2 -2
- package/.zcode/skills/orchestrate-project/SKILL.md +1 -1
- package/.zcode/skills/plan-refactor/SKILL.md +2 -2
- package/.zcode/skills/plan-release/SKILL.md +2 -2
- package/.zcode/skills/plan-work/SKILL.md +1 -1
- package/.zcode/skills/using-bigpowers/SKILL.md +2 -2
- package/.zcode/skills/wire-ci/SKILL.md +11 -14
- package/CHANGELOG.md +7 -0
- package/SKILL-INDEX.md +2 -2
- package/package.json +1 -1
- package/scripts/check-skill-links.py +35 -0
- package/scripts/land-branch.sh +9 -3
- package/scripts/lib/__pycache__/link_utils.cpython-312.pyc +0 -0
- package/scripts/lib/__pycache__/srp_engine_links.cpython-312.pyc +0 -0
- package/scripts/lib/golden-suite-gates.sh +4 -0
- package/scripts/lib/target-contracts.sh +37 -1
- package/scripts/test-target-contracts.sh +73 -0
- package/scripts/tombstone-skill.sh +6 -0
- package/skills/craft-skill/SKILL.md +2 -2
- package/skills/define-success/SKILL.md +7 -61
- package/skills/deploy/SKILL.md +1 -1
- package/skills/elaborate-spec/SKILL.md +1 -1
- package/skills/harden-vps/REFERENCE.md +39 -36
- package/skills/harden-vps/SKILL.md +24 -24
- package/skills/investigate-bug/SKILL.md +2 -2
- package/skills/orchestrate-project/REFERENCE.md +1 -1
- package/skills/plan-refactor/SKILL.md +2 -2
- package/skills/plan-release/SKILL.md +2 -2
- package/skills/plan-work/SKILL.md +1 -1
- package/skills/security-review/fixtures/CWE-639-idor-negative.go +1 -1
- package/skills/security-review/fixtures/CWE-639-idor-positive.go +1 -1
- package/skills/using-bigpowers/SKILL.md +2 -2
- package/skills/wire-ci/REFERENCE.md +11 -14
- package/skills-lock.json +12 -12
- package/.fix_regex.sh +0 -16
- package/.hermes-verify-sed-fix.py +0 -53
- package/_test_e28s01.sh +0 -2
- package/audit-independent-unwaived-2026-07-06.md +0 -49
- package/hermes-verify-sed-fix.py +0 -30
- package/instructions +0 -1
- package/scripts/hermes-verify-e39s02.sh +0 -28
- package/test_figlet.py +0 -17
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# story: e37s08
|
|
3
|
+
# test-target-contracts.sh — anti-vacuity guard for run_contract.
|
|
4
|
+
#
|
|
5
|
+
# Every contract named in scripts/targets.yaml must have a real assertion behind
|
|
6
|
+
# it. run_contract used to end in `*) echo "SKIP ..."; return 0`, so seven
|
|
7
|
+
# declared contracts (cline/codebuddy/codex/kilocode/qwen/trae/windsurf
|
|
8
|
+
# _hooks_manifest) silently passed forever. This test fails if that default ever
|
|
9
|
+
# returns to being permissive, or if targets.yaml declares a contract nothing
|
|
10
|
+
# implements.
|
|
11
|
+
#
|
|
12
|
+
# Usage: bash scripts/test-target-contracts.sh
|
|
13
|
+
set -euo pipefail
|
|
14
|
+
source "$(dirname "${BASH_SOURCE[0]}")/lib/skill-common.sh"
|
|
15
|
+
resolve_repo_root
|
|
16
|
+
cd "$REPO_ROOT"
|
|
17
|
+
|
|
18
|
+
PASS=0
|
|
19
|
+
FAIL=0
|
|
20
|
+
pass() { echo "PASS: $1"; PASS=$((PASS + 1)); }
|
|
21
|
+
fail() { echo "FAIL: $1" >&2; FAIL=$((FAIL + 1)); }
|
|
22
|
+
|
|
23
|
+
echo "=== test-target-contracts.sh ==="
|
|
24
|
+
|
|
25
|
+
# shellcheck source=lib/target-contracts.sh
|
|
26
|
+
source "$REPO_ROOT/scripts/lib/target-contracts.sh"
|
|
27
|
+
|
|
28
|
+
# 1. An unknown contract MUST fail. This is the anti-vacuity assertion.
|
|
29
|
+
set +e
|
|
30
|
+
out=$(run_contract "faketarget" "definitely_not_a_real_contract" 2>&1)
|
|
31
|
+
rc=$?
|
|
32
|
+
set -e
|
|
33
|
+
if [[ $rc -ne 0 ]]; then
|
|
34
|
+
pass "unknown contract fails (exit $rc)"
|
|
35
|
+
else
|
|
36
|
+
fail "unknown contract returned 0 — run_contract is fail-open again: $out"
|
|
37
|
+
fi
|
|
38
|
+
|
|
39
|
+
# 2. Every contract declared in targets.yaml must resolve to an assertion.
|
|
40
|
+
# Probing with a nonexistent target id means a real assertion returns 1 with
|
|
41
|
+
# a FAIL line, while a missing implementation hits the default branch and
|
|
42
|
+
# reports "unknown contract".
|
|
43
|
+
declared=$(grep -E "^ - [a-z0-9_]+$" scripts/targets.yaml | sed 's/^ - //' | sort -u)
|
|
44
|
+
[[ -n "$declared" ]] || fail "no contracts parsed from targets.yaml"
|
|
45
|
+
|
|
46
|
+
for c in $declared; do
|
|
47
|
+
set +e
|
|
48
|
+
out=$(run_contract "__probe__" "$c" 2>&1)
|
|
49
|
+
set -e
|
|
50
|
+
if grep -q "unknown contract" <<<"$out"; then
|
|
51
|
+
fail "$c declared in targets.yaml but no assertion implements it"
|
|
52
|
+
else
|
|
53
|
+
pass "$c has an implementation"
|
|
54
|
+
fi
|
|
55
|
+
done
|
|
56
|
+
|
|
57
|
+
# 3. Every *_hooks_manifest target must actually ship a parseable manifest.
|
|
58
|
+
for c in $declared; do
|
|
59
|
+
case "$c" in
|
|
60
|
+
gemini_hooks_manifest) continue ;; # adapter-level validator, not a file check
|
|
61
|
+
*_hooks_manifest)
|
|
62
|
+
t="${c%_hooks_manifest}"
|
|
63
|
+
if [[ -f "scripts/hooks/${t}/hooks-manifest.json" ]]; then
|
|
64
|
+
pass "$t ships hooks-manifest.json"
|
|
65
|
+
else
|
|
66
|
+
fail "$t declares $c but scripts/hooks/${t}/hooks-manifest.json is missing"
|
|
67
|
+
fi
|
|
68
|
+
;;
|
|
69
|
+
esac
|
|
70
|
+
done
|
|
71
|
+
|
|
72
|
+
echo "test-target-contracts: $PASS passed, $FAIL failed"
|
|
73
|
+
[[ "$FAIL" -eq 0 ]] || exit 1
|
|
@@ -54,9 +54,15 @@ STORY_TAGS=$(grep -E '^#\s*story:' "$OLD_SKILL_MD" || true)
|
|
|
54
54
|
CURRENT_VERSION=$(jq -r '.version' package.json 2>/dev/null)
|
|
55
55
|
CREATED_AT=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
|
|
56
56
|
|
|
57
|
+
# A tombstone is still a live SKILL.md for its transition window, so it must
|
|
58
|
+
# carry the same required frontmatter as any other skill. Omitting `model:`
|
|
59
|
+
# made docs/references/model-profiles.md count one fewer skill than there are
|
|
60
|
+
# skill directories, which fails validate-doctrine's skill-count check.
|
|
57
61
|
cat > "$OLD_SKILL_MD" <<STUBEOF
|
|
58
62
|
---
|
|
59
63
|
name: ${OLD_NAME}
|
|
64
|
+
model: haiku
|
|
65
|
+
effort: light
|
|
60
66
|
description: "TOMBSTONE — renamed/merged to ${NEW_NAME}. This stub resolves for one release then is removed."
|
|
61
67
|
---
|
|
62
68
|
|
|
@@ -48,7 +48,7 @@ Skill-body instructional prose MUST follow [AGENTIC-STE.md](../../docs/AGENTIC-S
|
|
|
48
48
|
- Any reference materials to include?
|
|
49
49
|
- What specs/ output does it produce (if any)?
|
|
50
50
|
|
|
51
|
-
2. **Verify Principles** — Ensure the skill aligns with [PRINCIPLES.md](
|
|
51
|
+
2. **Verify Principles** — Ensure the skill aligns with [PRINCIPLES.md](../../docs/PRINCIPLES.md):
|
|
52
52
|
- Is it atomic (verb-noun)?
|
|
53
53
|
- Is it "deep" (simple interface, complex internal logic)?
|
|
54
54
|
- Does it include Hard Gates?
|
|
@@ -62,7 +62,7 @@ Skill-body instructional prose MUST follow [AGENTIC-STE.md](../../docs/AGENTIC-S
|
|
|
62
62
|
**Auto-skill from library README:** When user provides a library README or API docs URL, extract triggers and HARD GATEs.
|
|
63
63
|
Draft verify commands and specs/ output into SKILL.md. Do NOT invent APIs not in the source.
|
|
64
64
|
|
|
65
|
-
4. Add `model:` frontmatter (`haiku` | `sonnet` | `opus`) per [model-profiles.md](
|
|
65
|
+
4. Add `model:` frontmatter (`haiku` | `sonnet` | `opus`) per [model-profiles.md](../../docs/references/model-profiles.md).
|
|
66
66
|
|
|
67
67
|
> **STREAM CONTINUITY** — When writing file content, output in continuous chunks of ~200 lines. Do not pause. Continue immediately until complete. If you need time, emit a placeholder comment rather than going silent.
|
|
68
68
|
|
|
@@ -1,69 +1,15 @@
|
|
|
1
|
-
ARCHIVED: content absorbed into plan-work
|
|
2
|
-
|
|
3
1
|
---
|
|
4
2
|
name: define-success
|
|
5
|
-
model:
|
|
6
|
-
effort:
|
|
7
|
-
description:
|
|
3
|
+
model: haiku
|
|
4
|
+
effort: light
|
|
5
|
+
description: "TOMBSTONE — renamed/merged to plan-work. This stub resolves for one release then is removed."
|
|
8
6
|
---
|
|
9
7
|
|
|
10
|
-
#
|
|
11
|
-
|
|
12
|
-
Transform "do X" into "step → verify: <cmd>" pairs. This is the pre-flight check before `plan-work` or `develop-tdd` — it makes success observable and removes ambiguity about when you're done.
|
|
13
|
-
|
|
14
|
-
> **HARD GATE** — Success criteria must be testable and user-observable. "Code should be fast" is not testable. "Pageload latency < 2s" is testable.
|
|
15
|
-
|
|
16
|
-
## Why this matters
|
|
17
|
-
|
|
18
|
-
"Implement user authentication" is not a plan. It has no checkpoints, no evidence requirement, and no way to know if you're done. The Karpathy principle: every step must be independently verifiable with a runnable command. If you can't verify it, you can't prove it works.
|
|
19
|
-
|
|
20
|
-
## Process
|
|
21
|
-
|
|
22
|
-
### 1. Read the task statement
|
|
23
|
-
|
|
24
|
-
Take the task as stated (from conversation, or from `specs/epics/ (see slice-tasks)`, or from `specs/product/SCOPE_LATEST.yaml`).
|
|
25
|
-
|
|
26
|
-
### 2. Break into observable outcomes
|
|
27
|
-
|
|
28
|
-
For each thing the task requires, identify:
|
|
29
|
-
- The smallest unit of observable behavior that proves something works
|
|
30
|
-
- The command that proves it
|
|
31
|
-
|
|
32
|
-
Work at the level of behaviors (what the system does) not implementation steps (how you'll write the code).
|
|
33
|
-
|
|
34
|
-
### 3. Write the pairs
|
|
35
|
-
|
|
36
|
-
Format each pair as:
|
|
37
|
-
```
|
|
38
|
-
N. [What must be true] → verify: <runnable command>
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
Examples:
|
|
42
|
-
|
|
43
|
-
```
|
|
44
|
-
Task: "Add user registration to the API"
|
|
45
|
-
|
|
46
|
-
1. POST /users accepts {email, name} and returns {id, email, name} → verify: curl -s -X POST http://localhost:3000/users -H 'Content-Type: application/json' -d '{"email":"test@test.com","name":"Test"}' | jq .id
|
|
47
|
-
2. Duplicate email is rejected with 409 → verify: npm test -- user-registration.test.ts
|
|
48
|
-
3. Missing email is rejected with 400 and descriptive error → verify: npm test -- user-validation.test.ts
|
|
49
|
-
4. Password is hashed (never stored in plaintext) → verify: npm test -- user-security.test.ts
|
|
50
|
-
5. All existing tests still pass → verify: npm test
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
### 4. Challenge completeness
|
|
54
|
-
|
|
55
|
-
Ask yourself:
|
|
56
|
-
- Is there any behavior the task requires that isn't covered by a verify step?
|
|
57
|
-
- Is every verify step runnable right now without additional setup?
|
|
58
|
-
- Does the final step verify the whole thing end-to-end?
|
|
59
|
-
|
|
60
|
-
Add any missing pairs.
|
|
61
|
-
|
|
62
|
-
### 5. Output
|
|
8
|
+
# define-success (tombstoned)
|
|
63
9
|
|
|
64
|
-
|
|
10
|
+
This skill has been renamed or merged into `plan-work`. Use `plan-work` instead.
|
|
65
11
|
|
|
66
|
-
|
|
12
|
+
This stub exists for one release as a transition aid, then is removed once
|
|
13
|
+
`scripts/validate-tombstones.sh` flags it as expired.
|
|
67
14
|
|
|
68
|
-
## Verify
|
|
69
15
|
|
package/skills/deploy/SKILL.md
CHANGED
|
@@ -74,7 +74,7 @@ Platform-agnostic — supports multiple deployment targets via environment varia
|
|
|
74
74
|
|----------|---------|---------|
|
|
75
75
|
| Vercel | `VERCEL_TOKEN`, `VERCEL_PROJECT_ID` | `vercel deploy --prod --token $VERCEL_TOKEN` |
|
|
76
76
|
| Netlify | `NETLIFY_AUTH_TOKEN`, `NETLIFY_SITE_ID` | `netlify deploy --prod --auth $NETLIFY_AUTH_TOKEN --dir $ARTIFACT_DIR` |
|
|
77
|
-
|
|
|
77
|
+
| Platform MCP | MCP tool call | `mcp deploy` via your platform MCP server |
|
|
78
78
|
| rsync/SSH | `DEPLOY_SSH_USER`, `DEPLOY_SSH_HOST`, `DEPLOY_SSH_PATH` | `rsync -avz $ARTIFACT_DIR/ $DEPLOY_SSH_USER@$DEPLOY_SSH_HOST:$DEPLOY_SSH_PATH` |
|
|
79
79
|
| Custom | `DEPLOY_COMMAND` | Run any deploy command string |
|
|
80
80
|
|
|
@@ -65,7 +65,7 @@ Once the user has answered the main questions, probe for assumptions:
|
|
|
65
65
|
|
|
66
66
|
### 4. Synthesize and confirm
|
|
67
67
|
|
|
68
|
-
Summarize your understanding in 3–5 bullet points aligned with [countable-story-format.md](
|
|
68
|
+
Summarize your understanding in 3–5 bullet points aligned with [countable-story-format.md](../../docs/countable-story-format.md):
|
|
69
69
|
- The problem (feeds into §1 Business narrative)
|
|
70
70
|
- The solution and main flow (feeds into §5)
|
|
71
71
|
- The key constraints and alternative flows (feeds into §6)
|
|
@@ -2,47 +2,47 @@
|
|
|
2
2
|
|
|
3
3
|
## Health check script
|
|
4
4
|
|
|
5
|
-
Deploy to `/opt/
|
|
5
|
+
Deploy to `/opt/your-app/scripts/healthcheck.sh`:
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
8
|
#!/bin/bash
|
|
9
|
-
LOG=/var/log/
|
|
10
|
-
mkdir -p /var/log/
|
|
9
|
+
LOG=/var/log/your-app/health.log
|
|
10
|
+
mkdir -p /var/log/your-app
|
|
11
11
|
DISK=$(df / | awk 'NR==2 {print $5}' | tr -d '%')
|
|
12
12
|
RAM=$(free | awk '/Mem:/ {printf "%.0f", $3/$2*100}')
|
|
13
13
|
NOW=$(date -Iseconds)
|
|
14
14
|
[ "$DISK" -gt 85 ] && echo "$NOW ALERT: Disk ${DISK}%" >> "$LOG"
|
|
15
15
|
[ "$RAM" -gt 90 ] && echo "$NOW ALERT: RAM ${RAM}%" >> "$LOG"
|
|
16
|
-
systemctl is-active --quiet
|
|
16
|
+
systemctl is-active --quiet your-app || { echo "$NOW ALERT: your application DOWN" >> "$LOG"; systemctl restart your-app; }
|
|
17
17
|
[ -f /var/run/reboot-required ] && echo "$NOW WARN: kernel reboot pending" >> "$LOG"
|
|
18
18
|
```
|
|
19
19
|
|
|
20
|
-
Make executable: `chmod +x /opt/
|
|
20
|
+
Make executable: `chmod +x /opt/your-app/scripts/healthcheck.sh`
|
|
21
21
|
|
|
22
|
-
##
|
|
22
|
+
## your application systemd unit
|
|
23
23
|
|
|
24
|
-
Full hardened unit at `/etc/systemd/system/
|
|
24
|
+
Full hardened unit at `/etc/systemd/system/your-app.service`:
|
|
25
25
|
|
|
26
26
|
```ini
|
|
27
27
|
[Unit]
|
|
28
|
-
Description=
|
|
29
|
-
Documentation=https://github.com/
|
|
28
|
+
Description=your application BaaS Platform
|
|
29
|
+
Documentation=https://github.com/example-org/example-app
|
|
30
30
|
After=network.target caddy.service
|
|
31
31
|
Wants=caddy.service
|
|
32
32
|
|
|
33
33
|
[Service]
|
|
34
34
|
Type=simple
|
|
35
|
-
User=
|
|
36
|
-
Group=
|
|
37
|
-
WorkingDirectory=/opt/
|
|
38
|
-
ExecStart=/opt/
|
|
35
|
+
User=your-app
|
|
36
|
+
Group=your-app
|
|
37
|
+
WorkingDirectory=/opt/your-app
|
|
38
|
+
ExecStart=/opt/your-app/bin/your-app serve \
|
|
39
39
|
--port 8080 \
|
|
40
|
-
--db /opt/
|
|
40
|
+
--db /opt/your-app/data/your-app.db \
|
|
41
41
|
--sites-domain <your-domain.example.com>
|
|
42
|
-
EnvironmentFile=-/opt/
|
|
43
|
-
Environment=
|
|
44
|
-
Environment=HOME=/opt/
|
|
45
|
-
Environment=NPM_CONFIG_CACHE=/opt/
|
|
42
|
+
EnvironmentFile=-/opt/your-app/.env
|
|
43
|
+
Environment=APP_HOME=/opt/your-app
|
|
44
|
+
Environment=HOME=/opt/your-app
|
|
45
|
+
Environment=NPM_CONFIG_CACHE=/opt/your-app/.npm
|
|
46
46
|
Environment=PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
|
|
47
47
|
Restart=always
|
|
48
48
|
RestartSec=5
|
|
@@ -59,11 +59,11 @@ ProtectKernelModules=yes
|
|
|
59
59
|
ProtectControlGroups=yes
|
|
60
60
|
RestrictAddressFamilies=AF_INET AF_INET6
|
|
61
61
|
RestrictRealtime=yes
|
|
62
|
-
ReadWritePaths=/opt/
|
|
63
|
-
ReadWritePaths=/opt/
|
|
64
|
-
ReadWritePaths=/opt/
|
|
65
|
-
ReadWritePaths=/opt/
|
|
66
|
-
ReadWritePaths=/opt/
|
|
62
|
+
ReadWritePaths=/opt/your-app/data
|
|
63
|
+
ReadWritePaths=/opt/your-app/backups
|
|
64
|
+
ReadWritePaths=/opt/your-app/secrets
|
|
65
|
+
ReadWritePaths=/opt/your-app/.npm
|
|
66
|
+
ReadWritePaths=/opt/your-app/logs
|
|
67
67
|
LimitNOFILE=65536
|
|
68
68
|
|
|
69
69
|
[Install]
|
|
@@ -83,17 +83,20 @@ bantime = 3600
|
|
|
83
83
|
findtime = 600
|
|
84
84
|
```
|
|
85
85
|
|
|
86
|
-
Note:
|
|
86
|
+
Note: your application auth jail deferred — your application logs to journald, not a file. To enable, use `backend = systemd` with a journald filter.
|
|
87
87
|
|
|
88
|
-
##
|
|
88
|
+
## provider-snapshot.sh — worked example (Contabo API)
|
|
89
89
|
|
|
90
|
-
|
|
90
|
+
> Snapshot APIs are provider-specific. This is one worked example, not a
|
|
91
|
+
> bigpowers default; swap the auth and endpoint calls for your own provider.
|
|
92
|
+
|
|
93
|
+
Deploy to `/opt/your-app/scripts/contabo-snapshot.sh`. Reads credentials from `/opt/your-app/.env` (same file used by your application systemd unit):
|
|
91
94
|
|
|
92
95
|
```bash
|
|
93
96
|
#!/bin/bash
|
|
94
97
|
set -e
|
|
95
|
-
LOG=/var/log/
|
|
96
|
-
ENVFILE=/opt/
|
|
98
|
+
LOG=/var/log/your-app/snapshot.log
|
|
99
|
+
ENVFILE=/opt/your-app/.env
|
|
97
100
|
INSTANCE_ID=<your-contabo-instance-id>
|
|
98
101
|
|
|
99
102
|
[ -f "$ENVFILE" ] || { echo "$(date -Iseconds) ERROR: $ENVFILE missing" >> "$LOG"; exit 1; }
|
|
@@ -122,9 +125,9 @@ echo >> "$LOG"
|
|
|
122
125
|
echo "$(date -Iseconds) Snapshot requested for $INSTANCE_ID" >> "$LOG"
|
|
123
126
|
```
|
|
124
127
|
|
|
125
|
-
##
|
|
128
|
+
## your VPS provider credentials
|
|
126
129
|
|
|
127
|
-
Add to `/opt/
|
|
130
|
+
Add to `/opt/your-app/.env` (same file used by your application systemd unit, deployed by GitHub Actions):
|
|
128
131
|
|
|
129
132
|
```
|
|
130
133
|
CONTABO_CLIENT_ID=
|
|
@@ -133,13 +136,13 @@ CONTABO_API_USER=
|
|
|
133
136
|
CONTABO_API_PASSWORD=
|
|
134
137
|
```
|
|
135
138
|
|
|
136
|
-
Source:
|
|
139
|
+
Source: your VPS provider Customer Control Panel → API Details. ClientId and ClientSecret are generated there. API User is your email. API Password is set separately in the panel.
|
|
137
140
|
|
|
138
|
-
**Pipeline:** GitHub Secrets → deploy workflow → `/opt/
|
|
141
|
+
**Pipeline:** GitHub Secrets → deploy workflow → `/opt/your-app/.env` on VPS. For local dev (`cntb get instances`), add to `.envrc`.
|
|
139
142
|
|
|
140
|
-
##
|
|
143
|
+
## your VPS provider instance info template
|
|
141
144
|
|
|
142
|
-
Fill in your instance details from the
|
|
145
|
+
Fill in your instance details from the your VPS provider Customer Control Panel:
|
|
143
146
|
|
|
144
147
|
```
|
|
145
148
|
IP: <your-instance-ip>
|
|
@@ -151,7 +154,7 @@ Default user: root
|
|
|
151
154
|
Customer ID: <your-customer-id>
|
|
152
155
|
```
|
|
153
156
|
|
|
154
|
-
##
|
|
157
|
+
## your application monitoring alert SQL
|
|
155
158
|
|
|
156
159
|
```sql
|
|
157
160
|
INSERT INTO monitoring_alerts (id, name, metric, threshold, operator, enabled, duration_seconds)
|
|
@@ -164,7 +167,7 @@ INSERT INTO monitoring_alerts (id, name, metric, threshold, operator, enabled, d
|
|
|
164
167
|
VALUES ('alert-003', 'VPS RAM above 85%', 'mem_used_percent', 85, 'gt', 1, 120);
|
|
165
168
|
```
|
|
166
169
|
|
|
167
|
-
Alerts are loaded at
|
|
170
|
+
Alerts are loaded at your application startup. Restart with `systemctl restart your-app` after inserting.
|
|
168
171
|
|
|
169
172
|
## Base64 encoding workaround
|
|
170
173
|
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: harden-vps
|
|
3
|
-
description: "Harden a production Linux VPS for
|
|
3
|
+
description: "Harden a production Linux VPS for your application across three layers — application (systemd hardening, monitoring alerts, backup automation), Ubuntu OS (UFW firewall, fail2ban SSH, unattended-upgrades, SSH hardening), and VPS provider (health checks, daily backups, monthly snapshots). Use when the user wants to secure a production server, harden a VPS, audit server security, or mentions production hardening, VPS security, or harden the server."
|
|
4
4
|
model: haiku
|
|
5
5
|
effort: standard
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
# Harden VPS
|
|
9
9
|
|
|
10
|
-
Three-layer production hardening for
|
|
10
|
+
Three-layer production hardening for a self-hosted app on any VPS. Each layer independently verifiable. Apply OS first (firewall blocks attacks immediately), then your application (alerts + backups), then your VPS provider (snapshots). See [REFERENCE.md](REFERENCE.md) for full script bodies, systemd unit template, and gotchas.
|
|
11
11
|
|
|
12
12
|
## Quick start
|
|
13
13
|
|
|
14
|
-
SSH as root into the VPS. Find credentials in the
|
|
14
|
+
SSH as root into the VPS. Find credentials in the your VPS provider Customer Control Panel.
|
|
15
15
|
|
|
16
16
|
> **HARD GATE** — Run `ufw status` first. No firewall = layer 1 takes priority over everything.
|
|
17
17
|
|
|
@@ -36,21 +36,21 @@ apt install -y unattended-upgrades && dpkg-reconfigure -plow unattended-upgrades
|
|
|
36
36
|
# SSH: PermitRootLogin no, PasswordAuthentication no, PubkeyAuthentication yes
|
|
37
37
|
# → verify: sshd -T | grep -E 'permitrootlogin no|passwordauthentication no'
|
|
38
38
|
|
|
39
|
-
# Deploy healthcheck.sh → /opt/
|
|
40
|
-
# Crontab: */5 * * * * /opt/
|
|
39
|
+
# Deploy healthcheck.sh → /opt/your-app/scripts/healthcheck.sh
|
|
40
|
+
# Crontab: */5 * * * * /opt/your-app/scripts/healthcheck.sh
|
|
41
41
|
```
|
|
42
42
|
|
|
43
|
-
## Layer 2 —
|
|
43
|
+
## Layer 2 — applicationlication
|
|
44
44
|
|
|
45
45
|
```bash
|
|
46
|
-
# systemd: User=
|
|
46
|
+
# systemd: User=your-app, NoNewPrivileges=yes, ProtectSystem=full,
|
|
47
47
|
# ProtectKernelTunables=yes, ProtectKernelModules=yes,
|
|
48
48
|
# ProtectControlGroups=yes, RestrictAddressFamilies=AF_INET AF_INET6,
|
|
49
49
|
# RestrictRealtime=yes, PrivateTmp=yes, LimitNOFILE=65536
|
|
50
|
-
# → verify: systemctl show
|
|
50
|
+
# → verify: systemctl show your-app -p NoNewPrivileges -p ProtectSystem -p User
|
|
51
51
|
|
|
52
|
-
# Alerts (
|
|
53
|
-
sqlite3 /opt/
|
|
52
|
+
# Alerts (your application requires auth; insert via SQLite)
|
|
53
|
+
sqlite3 /opt/your-app/data/your-app.db "
|
|
54
54
|
INSERT INTO monitoring_alerts (id,name,metric,threshold,operator,enabled,duration_seconds)
|
|
55
55
|
VALUES ('a1','Disk >80%','disk_used_percent',80,'gt',1,300);
|
|
56
56
|
INSERT INTO monitoring_alerts (id,name,metric,threshold,operator,enabled,duration_seconds)
|
|
@@ -58,14 +58,14 @@ VALUES ('a2','CPU >90%','cpu_percent',90,'gt',1,60);
|
|
|
58
58
|
INSERT INTO monitoring_alerts (id,name,metric,threshold,operator,enabled,duration_seconds)
|
|
59
59
|
VALUES ('a3','RAM >85%','mem_used_percent',85,'gt',1,120);
|
|
60
60
|
"
|
|
61
|
-
systemctl restart
|
|
61
|
+
systemctl restart your-app
|
|
62
62
|
|
|
63
63
|
# Backup crontab (root):
|
|
64
|
-
# 0 2 * * * cp /opt/
|
|
65
|
-
# 0 3 * * * find /backup/ -name "
|
|
64
|
+
# 0 2 * * * cp /opt/your-app/data/your-app.db /backup/your-app-$(date +\%Y\%m\%d).db
|
|
65
|
+
# 0 3 * * * find /backup/ -name "your-app-*.db" -mtime +90 -delete
|
|
66
66
|
```
|
|
67
67
|
|
|
68
|
-
## Layer 3 —
|
|
68
|
+
## Layer 3 — VPS provider
|
|
69
69
|
|
|
70
70
|
```bash
|
|
71
71
|
# cntb CLI
|
|
@@ -73,14 +73,14 @@ curl -sL "$(curl -sL https://api.github.com/repos/contabo/cntb/releases/latest \
|
|
|
73
73
|
| grep browser_download_url.*linux_amd64.tar.gz | head -1 | cut -d'"' -f4)" \
|
|
74
74
|
| tar xz -C /usr/local/bin
|
|
75
75
|
|
|
76
|
-
# Snapshot script → /opt/
|
|
77
|
-
# Credentials as env vars in /opt/
|
|
76
|
+
# Snapshot script → /opt/your-app/scripts/contabo-snapshot.sh (reads from /opt/your-app/.env)
|
|
77
|
+
# Credentials as env vars in /opt/your-app/.env (deployed by GitHub Actions):
|
|
78
78
|
# CONTABO_CLIENT_ID, CONTABO_CLIENT_SECRET, CONTABO_API_USER, CONTABO_API_PASSWORD
|
|
79
|
-
# Crontab: 0 4 1 * * /opt/
|
|
79
|
+
# Crontab: 0 4 1 * * /opt/your-app/scripts/contabo-snapshot.sh
|
|
80
80
|
|
|
81
81
|
# > HARD GATE — Snapshot cron silently fails until env vars are set in .env.
|
|
82
|
-
# Credentials source:
|
|
83
|
-
# Local dev: add to .envrc. Production: GitHub Secrets → deploy → /opt/
|
|
82
|
+
# Credentials source: your VPS provider Customer Panel → API Details.
|
|
83
|
+
# Local dev: add to .envrc. Production: GitHub Secrets → deploy → /opt/your-app/.env
|
|
84
84
|
```
|
|
85
85
|
|
|
86
86
|
## CRITICAL GOTCHAS
|
|
@@ -88,7 +88,7 @@ curl -sL "$(curl -sL https://api.github.com/repos/contabo/cntb/releases/latest \
|
|
|
88
88
|
1. **Shell escaping in Orca terminals:** `$VAR`, `$(…)`, and `%` get eaten by the local shell. Always use base64: `echo '<base64>' | base64 -d > script.sh`
|
|
89
89
|
2. **Crontab `%`:** cron interprets `%` as newline. Escape as `\%` in `$(date +\%Y\%m\%d)`
|
|
90
90
|
3. **fail2ban exit 255:** means a jail references a missing log file. Remove the broken jail, restart.
|
|
91
|
-
4. **
|
|
91
|
+
4. **your application alerts need auth:** POST to `/api/monitoring/alerts` requires Bearer token. Workaround: insert directly into SQLite, then restart your application.
|
|
92
92
|
|
|
93
93
|
## Verify all 8 gates
|
|
94
94
|
|
|
@@ -97,10 +97,10 @@ ufw status|grep -q active||echo FAIL:ufw
|
|
|
97
97
|
fail2ban-client status sshd>/dev/null 2>&1||echo FAIL:fail2ban
|
|
98
98
|
systemctl is-active unattended-upgrades|grep -q active||echo FAIL:unattended
|
|
99
99
|
sshd -T|grep -q 'permitrootlogin no'||echo FAIL:sshd
|
|
100
|
-
systemctl show
|
|
101
|
-
systemctl is-active
|
|
102
|
-
sqlite3 /opt/
|
|
103
|
-
crontab -l|grep -q healthcheck&&crontab -l|grep -q
|
|
100
|
+
systemctl show your-app -p NoNewPrivileges|grep -q yes||echo FAIL:systemd
|
|
101
|
+
systemctl is-active your-app|grep -q active||echo FAIL:your-app
|
|
102
|
+
sqlite3 /opt/your-app/data/your-app.db "SELECT count(*) FROM monitoring_alerts"|grep -q 3||echo FAIL:alerts
|
|
103
|
+
crontab -l|grep -q healthcheck&&crontab -l|grep -q your-app.db&&crontab -l|grep -q contabo-snapshot||echo FAIL:crontab
|
|
104
104
|
echo ALL 8 GATES PASSED
|
|
105
105
|
```
|
|
106
106
|
|
|
@@ -124,6 +124,6 @@ After writing the bug file, print a one-line summary of the root cause and sugge
|
|
|
124
124
|
|
|
125
125
|
<!-- story: e35s10 -->
|
|
126
126
|
|
|
127
|
-
- [Feathers' Seams & Characterization Tests](
|
|
128
|
-
- [Fowler's Code Smells](
|
|
127
|
+
- [Feathers' Seams & Characterization Tests](../../docs/references/feathers.md) — seam types, characterization tests, and the legacy code change algorithm
|
|
128
|
+
- [Fowler's Code Smells](../../docs/references/fowler.md) — identifying structural problems by smell before investigating
|
|
129
129
|
|
|
@@ -19,7 +19,7 @@ Detailed documentation for the `orchestrate-project` meta-skill.
|
|
|
19
19
|
### PHASE 3: PLAN
|
|
20
20
|
- **Goal**: Write a verifiable implementation plan with success criteria.
|
|
21
21
|
- **Deliverables**: `release-plan.yaml`, `epics/eNN-*.yaml` with `verify:` per task.
|
|
22
|
-
- **Skills**: `scope-work`, `slice-tasks`, `
|
|
22
|
+
- **Skills**: `scope-work`, `slice-tasks`, `plan-work`.
|
|
23
23
|
- **Gate**: Quality (request-review ≥94%) + slopcheck [SUS]/[SLOP].
|
|
24
24
|
|
|
25
25
|
### PHASE 4: BUILD
|
|
@@ -82,8 +82,8 @@ After writing `specs/REFACTOR_LATEST.md`, suggest running `kickoff-branch` next
|
|
|
82
82
|
|
|
83
83
|
<!-- story: e35s10 -->
|
|
84
84
|
|
|
85
|
-
- [Fowler's Refactoring Catalog](
|
|
86
|
-
- [Beck's Tidy First?](
|
|
85
|
+
- [Fowler's Refactoring Catalog](../../docs/references/fowler.md) — canonical refactoring vocabulary and code-smell taxonomy
|
|
86
|
+
- [Beck's Tidy First?](../../docs/references/kent-beck.md) — structural change before behavioral change
|
|
87
87
|
|
|
88
88
|
## Verify
|
|
89
89
|
|
|
@@ -17,7 +17,7 @@ Synthesize the conversation context into `specs/release-plan.yaml` (index) and s
|
|
|
17
17
|
|------|---------|
|
|
18
18
|
| `specs/release-plan.yaml` | `release.version`, semver bump hint, WSJF-ordered epic list with `id`, `capsule_dir`, `wsjf`, `bcps` — **no story status** |
|
|
19
19
|
| `specs/epics/eNN-<slug>/epic.yaml` | Epic manifest: `id`, `title`, `wsjf`, `total_bcps`, `status`, `stories[]` list |
|
|
20
|
-
| `specs/epics/eNN-<slug>/eNNsYY-<slug>.md` | Story spec in [countable-story-format.md](
|
|
20
|
+
| `specs/epics/eNN-<slug>/eNNsYY-<slug>.md` | Story spec in [countable-story-format.md](../../docs/countable-story-format.md) with 20 sections and Gherkin acceptance criteria |
|
|
21
21
|
| `specs/epics/eNN-<slug>/eNNsYY-tasks.yaml` | Decoupled task checklist with `verify:` commands per task |
|
|
22
22
|
| `specs/execution-status.yaml` | Flat key-value store for story status (`eNNsYY: todo`) |
|
|
23
23
|
|
|
@@ -102,7 +102,7 @@ stories:
|
|
|
102
102
|
```
|
|
103
103
|
### 6. Save story specs (countable-story-format .md)
|
|
104
104
|
|
|
105
|
-
Each story becomes a standalone `.md` file following [countable-story-format.md](
|
|
105
|
+
Each story becomes a standalone `.md` file following [countable-story-format.md](../../docs/countable-story-format.md). Minimum: maturity 3 (Countable) with all 20 sections present. Acceptance criteria in §17 use Gherkin scenarios.
|
|
106
106
|
### 7. Save decoupled task files (`-tasks.yaml`)
|
|
107
107
|
|
|
108
108
|
Each story has a decoupled `-tasks.yaml` with implementation steps:
|
|
@@ -18,7 +18,7 @@ description: "PLANNING SPINE STEP 3 of 3 — Plan the work: write detailed imple
|
|
|
18
18
|
|
|
19
19
|
Produce a detailed, verifiable implementation plan in the **active epic capsule directory** (`specs/epics/eNN-slug/`). Output: a story spec `.md` file (countable-story-format) and a decoupled `eNNsYY-tasks.yaml` with runnable verify commands. "I think it works" is not a step.
|
|
20
20
|
|
|
21
|
-
> **HARD GATE** — Do NOT proceed with a plan until the task's success criteria are clear. If success is ambiguous,
|
|
21
|
+
> **HARD GATE** — Do NOT proceed with a plan until the task's success criteria are clear. If success is ambiguous, convert the task into "step → verify: `<cmd>`" pairs here before writing tasks — every task ships a runnable `verify:` or the plan is not done.
|
|
22
22
|
>
|
|
23
23
|
> **RECURSIVE DISCIPLINE** — This lifecycle applies to EVERY task, including updating these skills. Never skip planning because a task is "meta" or "just documentation."
|
|
24
24
|
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
// is part of the WHERE clause. A caller from another organization gets zero
|
|
6
6
|
// rows rather than someone else's site.
|
|
7
7
|
//
|
|
8
|
-
// Note the retrofit trap this deliberately avoids:
|
|
8
|
+
// Note the retrofit trap this deliberately avoids: a real-world IDOR retrofit (BUG-2026-07-24T184443)
|
|
9
9
|
// added `org_id INTEGER NOT NULL DEFAULT 0`, which passed tests on new rows and
|
|
10
10
|
// hid 8 of 9 production sites whose legacy rows defaulted to org 0. Scope on a
|
|
11
11
|
// real, backfilled org_id — never a placeholder default.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// story: e80s05
|
|
2
2
|
// Positive fixture: IDOR / missing tenant scoping (must be flagged).
|
|
3
3
|
//
|
|
4
|
-
// Modelled on
|
|
4
|
+
// Modelled on a real-world bug family (BUG-129/130/133/135/136/140/143): the
|
|
5
5
|
// handler authenticates the caller, then trusts an ID from the request and
|
|
6
6
|
// queries by that ID alone. Authentication is proven; authorization is not.
|
|
7
7
|
// Nothing in the type system or a diff-scoped review makes this look wrong —
|
|
@@ -9,7 +9,7 @@ description: One-time bootstrap that introduces the bigpowers skills system, the
|
|
|
9
9
|
> **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.
|
|
10
10
|
|
|
11
11
|
|
|
12
|
-
Welcome to **bigpowers** — a lifecycle of
|
|
12
|
+
Welcome to **bigpowers** — a lifecycle of agent skills for production-ready, TDD-driven software by solo developers. The live catalog and its count are generated in [`SKILL-INDEX.md`](../../SKILL-INDEX.md); never hardcode the number here.
|
|
13
13
|
|
|
14
14
|
## Install
|
|
15
15
|
|
|
@@ -38,7 +38,7 @@ DISCOVER survey-context → research-first → elaborate-spec
|
|
|
38
38
|
↓
|
|
39
39
|
DESIGN model-domain / define-language / grill-me / deepen-architecture / design-interface
|
|
40
40
|
↓
|
|
41
|
-
PLAN scope-work → slice-tasks →
|
|
41
|
+
PLAN scope-work → slice-tasks → plan-work / plan-refactor
|
|
42
42
|
↓
|
|
43
43
|
INITIATE kickoff-branch → guard-git / hook-commits / seed-conventions
|
|
44
44
|
↓
|
|
@@ -145,7 +145,7 @@ jobs:
|
|
|
145
145
|
|
|
146
146
|
---
|
|
147
147
|
|
|
148
|
-
## Reference block 2 — deploy.yml (
|
|
148
|
+
## Reference block 2 — deploy.yml (generic web app, excerpt)
|
|
149
149
|
|
|
150
150
|
```yaml
|
|
151
151
|
name: Deploy
|
|
@@ -163,7 +163,7 @@ concurrency:
|
|
|
163
163
|
cancel-in-progress: false
|
|
164
164
|
|
|
165
165
|
env:
|
|
166
|
-
SITE_URL: "https://CHANGE-ME.
|
|
166
|
+
SITE_URL: "https://CHANGE-ME.example.com"
|
|
167
167
|
|
|
168
168
|
jobs:
|
|
169
169
|
deploy:
|
|
@@ -179,18 +179,15 @@ jobs:
|
|
|
179
179
|
github-token: ${{ secrets.GITHUB_TOKEN }}
|
|
180
180
|
run-id: ${{ github.event.workflow_run.id }}
|
|
181
181
|
path: deploy-meta
|
|
182
|
-
#
|
|
183
|
-
#
|
|
184
|
-
#
|
|
185
|
-
#
|
|
186
|
-
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
deploy_token: ${{ secrets.BIGBASE_DEPLOY_TOKEN }}
|
|
192
|
-
ref: ${{ steps.meta.outputs.ref }}
|
|
193
|
-
skip_health_check: true
|
|
182
|
+
# Placeholder deploy step — bigpowers ships no deploy templates and pins
|
|
183
|
+
# no third-party action. Substitute your platform's own step here, or drop
|
|
184
|
+
# the deploy job entirely for CLI and library repos. Pin whatever action
|
|
185
|
+
# you choose to a full commit SHA rather than a tag. (GH #104)
|
|
186
|
+
- name: Deploy
|
|
187
|
+
run: |
|
|
188
|
+
echo "Replace this step with your platform's deploy command."
|
|
189
|
+
echo "commit=$(jq -r .sha deploy-meta/deploy-meta.json)"
|
|
190
|
+
exit 1
|
|
194
191
|
- name: Health check
|
|
195
192
|
run: |
|
|
196
193
|
curl -sf "${{ env.SITE_URL }}" || exit 1
|