@metasession.co/devaudit-cli 0.1.1 → 0.1.2
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.md +13 -10
- package/dist/index.js +17 -5
- package/dist/index.js.map +1 -1
- package/package.json +9 -5
- package/scripts/upload-evidence.sh +225 -0
- package/sdlc/.claude/settings.local.json +11 -0
- package/sdlc/CLAUDE.md +73 -0
- package/sdlc/HOST_ADAPTER.md +127 -0
- package/sdlc/SKILLS.md +137 -0
- package/sdlc/STACK_ADAPTER.md +130 -0
- package/sdlc/ai-rules/INSTRUCTIONS-SDLC.md +172 -0
- package/sdlc/ai-rules/README.md +103 -0
- package/sdlc/ai-rules/SDLC_RULES.md +584 -0
- package/sdlc/ai-rules/claude/CLAUDE.md +192 -0
- package/sdlc/ai-rules/cursor/.cursorrules +167 -0
- package/sdlc/ai-rules/windsurf/.windsurfrules +167 -0
- package/sdlc/article.md +219 -0
- package/sdlc/files/_common/0-project-setup.md +410 -0
- package/sdlc/files/_common/1-plan-requirement.md +381 -0
- package/sdlc/files/_common/2-implement-and-test.md +276 -0
- package/sdlc/files/_common/3-compile-evidence.md +603 -0
- package/sdlc/files/_common/4-submit-for-review.md +362 -0
- package/sdlc/files/_common/5-deploy-main.md +251 -0
- package/sdlc/files/_common/Periodic_Security_Review_Schedule.md +169 -0
- package/sdlc/files/_common/README_TEMPLATE.md +441 -0
- package/sdlc/files/_common/Test_Architecture.md +461 -0
- package/sdlc/files/_common/Test_Plan_TEMPLATE.md +311 -0
- package/sdlc/files/_common/Test_Policy.md +277 -0
- package/sdlc/files/_common/Test_Strategy.md +359 -0
- package/sdlc/files/_common/github/ISSUE_TEMPLATE/bug.yml +75 -0
- package/sdlc/files/_common/github/ISSUE_TEMPLATE/config.yml +11 -0
- package/sdlc/files/_common/github/ISSUE_TEMPLATE/requirement.yml +75 -0
- package/sdlc/files/_common/github/ISSUE_TEMPLATE/task.yml +48 -0
- package/sdlc/files/_common/github/pull_request_template.md +69 -0
- package/sdlc/files/_common/implementing-an-sdlc-issue.md +413 -0
- package/sdlc/files/_common/scripts/derive-release-version.sh +40 -0
- package/sdlc/files/_common/scripts/derive-release-version.test.sh +98 -0
- package/sdlc/files/_common/scripts/submit-for-uat-review.sh +162 -0
- package/sdlc/files/_common/scripts/validate-commits.sh +83 -0
- package/sdlc/files/_common/scripts/validate-compliance-artifacts.sh +202 -0
- package/sdlc/files/_common/scripts/validate-compliance-artifacts.test.sh +202 -0
- package/sdlc/files/_common/skills/_schema/skill.schema.json +36 -0
- package/sdlc/files/_common/skills/e2e-test-engineer/SKILL.md +254 -0
- package/sdlc/files/_common/skills/e2e-test-engineer/references/bootstrap.md +244 -0
- package/sdlc/files/_common/skills/e2e-test-engineer/references/evidence.ts +40 -0
- package/sdlc/files/_common/skills/sdlc-implementer/SKILL.md +189 -0
- package/sdlc/files/_common/skills/sdlc-implementer/references/call-graph.md +64 -0
- package/sdlc/files/_common/skills/sdlc-implementer/references/change-request-loop.md +192 -0
- package/sdlc/files/_common/skills/sdlc-implementer/references/compliance-constraints.md +81 -0
- package/sdlc/files/ci/check-release-approval.yml.template +201 -0
- package/sdlc/files/ci/ci-status-fallback.yml.template +41 -0
- package/sdlc/files/ci/ci.yml.template +390 -0
- package/sdlc/files/ci/compliance-evidence.yml.template +161 -0
- package/sdlc/files/ci/compliance-validation.yml.template +34 -0
- package/sdlc/files/ci/post-deploy-prod.yml.template +159 -0
- package/sdlc/files/ci/python/ci.yml.template +335 -0
- package/sdlc/files/hosts/_schema/adapter.schema.json +103 -0
- package/sdlc/files/hosts/railway/adapter.json +32 -0
- package/sdlc/files/sdlc-config.example.json +74 -0
- package/sdlc/files/stacks/_schema/adapter.schema.json +151 -0
- package/sdlc/files/stacks/node/adapter.json +54 -0
- package/sdlc/files/stacks/node/hooks/.prettierrc.json +9 -0
- package/sdlc/files/stacks/node/hooks/commit-msg +7 -0
- package/sdlc/files/stacks/node/hooks/commitlint.config.mjs +64 -0
- package/sdlc/files/stacks/node/hooks/lint-staged.config.mjs +16 -0
- package/sdlc/files/stacks/node/hooks/pre-commit +13 -0
- package/sdlc/files/stacks/node/hooks/pre-push +15 -0
- package/sdlc/files/stacks/node/scripts/check-requirement-jsdoc.sh +54 -0
- package/sdlc/files/stacks/python/adapter.json +36 -0
- package/sdlc/files/stacks/python/hooks/.pre-commit-config.yaml +51 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@metasession.co/devaudit-cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "DevAudit CLI — installs, syncs, and operates the Metasession SDLC across consumer projects.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -13,6 +13,8 @@
|
|
|
13
13
|
"files": [
|
|
14
14
|
"bin",
|
|
15
15
|
"dist",
|
|
16
|
+
"sdlc",
|
|
17
|
+
"scripts",
|
|
16
18
|
"README.md",
|
|
17
19
|
"LICENSE"
|
|
18
20
|
],
|
|
@@ -22,25 +24,27 @@
|
|
|
22
24
|
"scripts": {
|
|
23
25
|
"build": "tsup",
|
|
24
26
|
"dev": "tsup --watch",
|
|
27
|
+
"bundle:templates": "node tools/bundle-templates.mjs",
|
|
28
|
+
"prepack": "npm run build && npm run bundle:templates",
|
|
25
29
|
"test": "vitest run",
|
|
26
30
|
"test:watch": "vitest",
|
|
27
31
|
"typecheck": "tsc --noEmit",
|
|
28
32
|
"start": "node ./bin/devaudit.js"
|
|
29
33
|
},
|
|
30
34
|
"dependencies": {
|
|
31
|
-
"commander": "^12.1.0",
|
|
32
35
|
"@clack/prompts": "^0.8.2",
|
|
36
|
+
"@metasession.co/devaudit-plugin-sdk": "file:../plugin-sdk",
|
|
37
|
+
"commander": "^12.1.0",
|
|
33
38
|
"consola": "^3.2.3",
|
|
34
|
-
"execa": "^9.5.1",
|
|
35
39
|
"env-paths": "^3.0.0",
|
|
36
|
-
"
|
|
40
|
+
"execa": "^9.5.1"
|
|
37
41
|
},
|
|
38
42
|
"devDependencies": {
|
|
39
43
|
"@types/node": "^22.9.0",
|
|
40
44
|
"msw": "^2.7.0",
|
|
41
45
|
"tsup": "^8.3.5",
|
|
42
46
|
"typescript": "^5.7.2",
|
|
43
|
-
"vitest": "^
|
|
47
|
+
"vitest": "^4.1.6"
|
|
44
48
|
},
|
|
45
49
|
"publishConfig": {
|
|
46
50
|
"access": "public"
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# @requirement REQ-007 - CLI upload script for CI pipelines
|
|
3
|
+
# @requirement REQ-020 - Extended with release/environment/category flags
|
|
4
|
+
# @requirement REQ-XXX - #224: posts to META-COMPLY's API instead of Supabase
|
|
5
|
+
#
|
|
6
|
+
# Usage:
|
|
7
|
+
# ./scripts/upload-evidence.sh <project-slug> <requirement-id> <evidence-type> <file-or-directory>
|
|
8
|
+
#
|
|
9
|
+
# Optional flags:
|
|
10
|
+
# --git-sha <sha> Git commit SHA
|
|
11
|
+
# --ci-run-id <id> CI run identifier
|
|
12
|
+
# --branch <branch> Git branch name
|
|
13
|
+
# --release <version> Release version (e.g. v1.0.0). The route
|
|
14
|
+
# resolves it to a release UUID server-side.
|
|
15
|
+
# --create-release-if-missing Auto-create the release as 'draft' if absent
|
|
16
|
+
# --environment <env> Environment: uat or production
|
|
17
|
+
# --category <cat> Evidence category: ci_pipeline, local_dev,
|
|
18
|
+
# planning, test_report, security_scan,
|
|
19
|
+
# release_artifact
|
|
20
|
+
#
|
|
21
|
+
# Required environment variables:
|
|
22
|
+
# DEVAUDIT_BASE_URL e.g. https://meta-comply-production.up.railway.app
|
|
23
|
+
# DEVAUDIT_API_KEY project-scoped API key (uploader role); format `mc_…`.
|
|
24
|
+
# Issue from: Project Settings → API Keys in
|
|
25
|
+
# META-COMPLY's web UI.
|
|
26
|
+
#
|
|
27
|
+
# Examples:
|
|
28
|
+
# ./scripts/upload-evidence.sh meta-ats REQ-001 screenshot \
|
|
29
|
+
# compliance/evidence/REQ-001/screenshots/
|
|
30
|
+
# ./scripts/upload-evidence.sh meta-ats _compliance-docs compliance_document \
|
|
31
|
+
# compliance/RTM.md --git-sha abc123
|
|
32
|
+
# ./scripts/upload-evidence.sh meta-ats REQ-001 e2e_result \
|
|
33
|
+
# playwright-report/ --release v1.0.0 --environment uat \
|
|
34
|
+
# --category ci_pipeline --create-release-if-missing
|
|
35
|
+
|
|
36
|
+
set -euo pipefail
|
|
37
|
+
|
|
38
|
+
# --- Parse arguments ---
|
|
39
|
+
if [ "$#" -lt 4 ]; then
|
|
40
|
+
echo "Usage: $0 <project-slug> <requirement-id> <evidence-type> <file-or-directory> [flags…]"
|
|
41
|
+
exit 1
|
|
42
|
+
fi
|
|
43
|
+
|
|
44
|
+
PROJECT_SLUG="$1"
|
|
45
|
+
REQUIREMENT_ID="$2"
|
|
46
|
+
EVIDENCE_TYPE="$3"
|
|
47
|
+
FILE_PATH="$4"
|
|
48
|
+
shift 4
|
|
49
|
+
|
|
50
|
+
GIT_SHA=""
|
|
51
|
+
CI_RUN_ID=""
|
|
52
|
+
BRANCH=""
|
|
53
|
+
RELEASE_VERSION=""
|
|
54
|
+
CREATE_RELEASE_IF_MISSING=false
|
|
55
|
+
ENVIRONMENT=""
|
|
56
|
+
EVIDENCE_CATEGORY=""
|
|
57
|
+
|
|
58
|
+
while [ "$#" -gt 0 ]; do
|
|
59
|
+
case "$1" in
|
|
60
|
+
--git-sha) GIT_SHA="$2"; shift 2 ;;
|
|
61
|
+
--ci-run-id) CI_RUN_ID="$2"; shift 2 ;;
|
|
62
|
+
--branch) BRANCH="$2"; shift 2 ;;
|
|
63
|
+
--release) RELEASE_VERSION="$2"; shift 2 ;;
|
|
64
|
+
--create-release-if-missing) CREATE_RELEASE_IF_MISSING=true; shift ;;
|
|
65
|
+
--environment) ENVIRONMENT="$2"; shift 2 ;;
|
|
66
|
+
--category) EVIDENCE_CATEGORY="$2"; shift 2 ;;
|
|
67
|
+
*) echo "Unknown option: $1"; exit 1 ;;
|
|
68
|
+
esac
|
|
69
|
+
done
|
|
70
|
+
|
|
71
|
+
if [ -n "$ENVIRONMENT" ] && [ -z "$RELEASE_VERSION" ]; then
|
|
72
|
+
echo "Error: --environment requires --release (evidence without a release is orphaned)"
|
|
73
|
+
exit 1
|
|
74
|
+
fi
|
|
75
|
+
if [ -n "$RELEASE_VERSION" ] && [ -z "$EVIDENCE_CATEGORY" ]; then
|
|
76
|
+
echo "Error: --category is required when --release is specified (gate validation)"
|
|
77
|
+
exit 1
|
|
78
|
+
fi
|
|
79
|
+
|
|
80
|
+
if [ -z "${DEVAUDIT_BASE_URL:-}" ]; then
|
|
81
|
+
echo "Error: DEVAUDIT_BASE_URL environment variable is required"
|
|
82
|
+
exit 1
|
|
83
|
+
fi
|
|
84
|
+
if [ -z "${DEVAUDIT_API_KEY:-}" ]; then
|
|
85
|
+
echo "Error: DEVAUDIT_API_KEY environment variable is required (issue from"
|
|
86
|
+
echo " Project Settings → API Keys in META-COMPLY)"
|
|
87
|
+
exit 1
|
|
88
|
+
fi
|
|
89
|
+
|
|
90
|
+
# Strip any trailing slash so we don't double-up later.
|
|
91
|
+
DEVAUDIT_BASE_URL="${DEVAUDIT_BASE_URL%/}"
|
|
92
|
+
|
|
93
|
+
# --- Build metadata JSON ---
|
|
94
|
+
METADATA="{}"
|
|
95
|
+
if [ -n "$GIT_SHA" ] || [ -n "$CI_RUN_ID" ] || [ -n "$BRANCH" ]; then
|
|
96
|
+
METADATA="{"
|
|
97
|
+
FIRST=true
|
|
98
|
+
if [ -n "$GIT_SHA" ]; then
|
|
99
|
+
METADATA="${METADATA}\"gitSha\":\"${GIT_SHA}\""
|
|
100
|
+
FIRST=false
|
|
101
|
+
fi
|
|
102
|
+
if [ -n "$CI_RUN_ID" ]; then
|
|
103
|
+
[ "$FIRST" = false ] && METADATA="${METADATA},"
|
|
104
|
+
METADATA="${METADATA}\"ciRunId\":\"${CI_RUN_ID}\""
|
|
105
|
+
FIRST=false
|
|
106
|
+
fi
|
|
107
|
+
if [ -n "$BRANCH" ]; then
|
|
108
|
+
[ "$FIRST" = false ] && METADATA="${METADATA},"
|
|
109
|
+
METADATA="${METADATA}\"branch\":\"${BRANCH}\""
|
|
110
|
+
fi
|
|
111
|
+
METADATA="${METADATA}}"
|
|
112
|
+
fi
|
|
113
|
+
|
|
114
|
+
# --- Collect files ---
|
|
115
|
+
FILES=()
|
|
116
|
+
if [ -d "$FILE_PATH" ]; then
|
|
117
|
+
while IFS= read -r -d '' f; do
|
|
118
|
+
FILES+=("$f")
|
|
119
|
+
done < <(find "$FILE_PATH" -type f -print0)
|
|
120
|
+
else
|
|
121
|
+
FILES=("$FILE_PATH")
|
|
122
|
+
fi
|
|
123
|
+
if [ ${#FILES[@]} -eq 0 ]; then
|
|
124
|
+
echo "Error: No files found at $FILE_PATH"
|
|
125
|
+
exit 1
|
|
126
|
+
fi
|
|
127
|
+
|
|
128
|
+
# --- Upload each file via /api/evidence/upload ---
|
|
129
|
+
#
|
|
130
|
+
# Retry-on-429 / 5xx: consumer CI workflows fire 8-12 sequential uploads per
|
|
131
|
+
# requirement (test-scope, test-plan, implementation-plan, security-summary,
|
|
132
|
+
# test-execution-summary, ai-prompts, ai-use-note, uat-checklist, gates/*.json).
|
|
133
|
+
# That cadence trips DevAudit's per-IP rate limiter, marking otherwise-green
|
|
134
|
+
# CI runs as failed. Retry transiently with exponential backoff (1s → 16s),
|
|
135
|
+
# honouring Retry-After if the portal supplies it. Auth/validation errors
|
|
136
|
+
# (4xx other than 429) still fail fast — they won't fix themselves.
|
|
137
|
+
#
|
|
138
|
+
# Issue: devaudit#263.
|
|
139
|
+
SUCCEEDED=0
|
|
140
|
+
FAILED=0
|
|
141
|
+
TOTAL_SIZE=0
|
|
142
|
+
UPLOAD_URL="${DEVAUDIT_BASE_URL}/api/evidence/upload"
|
|
143
|
+
MAX_ATTEMPTS=${UPLOAD_MAX_ATTEMPTS:-5}
|
|
144
|
+
INITIAL_BACKOFF_SECONDS=${UPLOAD_INITIAL_BACKOFF_SECONDS:-1}
|
|
145
|
+
|
|
146
|
+
for FILE in "${FILES[@]}"; do
|
|
147
|
+
FILENAME=$(basename "$FILE")
|
|
148
|
+
FILE_SIZE=$(stat -c%s "$FILE" 2>/dev/null || stat -f%z "$FILE")
|
|
149
|
+
echo -n "Uploading ${FILENAME}... "
|
|
150
|
+
CURL_ARGS=(
|
|
151
|
+
-X POST "$UPLOAD_URL"
|
|
152
|
+
-H "Authorization: Bearer ${DEVAUDIT_API_KEY}"
|
|
153
|
+
-F "file=@${FILE}"
|
|
154
|
+
-F "projectSlug=${PROJECT_SLUG}"
|
|
155
|
+
-F "requirementId=${REQUIREMENT_ID}"
|
|
156
|
+
-F "evidenceType=${EVIDENCE_TYPE}"
|
|
157
|
+
-F "metadata=${METADATA}"
|
|
158
|
+
)
|
|
159
|
+
[ -n "$RELEASE_VERSION" ] && CURL_ARGS+=(-F "releaseVersion=${RELEASE_VERSION}")
|
|
160
|
+
if [ "$CREATE_RELEASE_IF_MISSING" = true ]; then
|
|
161
|
+
CURL_ARGS+=(-F "createReleaseIfMissing=true")
|
|
162
|
+
fi
|
|
163
|
+
[ -n "$BRANCH" ] && CURL_ARGS+=(-F "releaseBranch=${BRANCH}")
|
|
164
|
+
[ -n "$ENVIRONMENT" ] && CURL_ARGS+=(-F "environment=${ENVIRONMENT}")
|
|
165
|
+
[ -n "$EVIDENCE_CATEGORY" ] && CURL_ARGS+=(-F "evidenceCategory=${EVIDENCE_CATEGORY}")
|
|
166
|
+
|
|
167
|
+
ATTEMPT=1
|
|
168
|
+
BACKOFF=$INITIAL_BACKOFF_SECONDS
|
|
169
|
+
HTTP_CODE=0
|
|
170
|
+
RESP_BODY_FILE=""
|
|
171
|
+
while [ "$ATTEMPT" -le "$MAX_ATTEMPTS" ]; do
|
|
172
|
+
[ -n "$RESP_BODY_FILE" ] && rm -f "$RESP_BODY_FILE"
|
|
173
|
+
RESP_BODY_FILE=$(mktemp)
|
|
174
|
+
RESP_HEADERS_FILE=$(mktemp)
|
|
175
|
+
HTTP_CODE=$(curl -s -o "$RESP_BODY_FILE" -D "$RESP_HEADERS_FILE" -w "%{http_code}" "${CURL_ARGS[@]}")
|
|
176
|
+
if [ "$HTTP_CODE" -ge 200 ] && [ "$HTTP_CODE" -lt 300 ]; then
|
|
177
|
+
rm -f "$RESP_HEADERS_FILE"
|
|
178
|
+
break
|
|
179
|
+
fi
|
|
180
|
+
# Decide whether the failure is retriable (429 or 5xx).
|
|
181
|
+
if [ "$HTTP_CODE" = "429" ] || { [ "$HTTP_CODE" -ge 500 ] && [ "$HTTP_CODE" -lt 600 ]; }; then
|
|
182
|
+
if [ "$ATTEMPT" -lt "$MAX_ATTEMPTS" ]; then
|
|
183
|
+
# Honour Retry-After (seconds) if the portal supplied it; otherwise back off.
|
|
184
|
+
WAIT_SECONDS=$BACKOFF
|
|
185
|
+
RETRY_AFTER=$(grep -i '^retry-after:' "$RESP_HEADERS_FILE" 2>/dev/null | head -1 | sed 's/^[Rr]etry-[Aa]fter:[[:space:]]*//' | tr -d '\r')
|
|
186
|
+
if [[ "$RETRY_AFTER" =~ ^[0-9]+$ ]] && [ "$RETRY_AFTER" -gt 0 ]; then
|
|
187
|
+
WAIT_SECONDS=$RETRY_AFTER
|
|
188
|
+
fi
|
|
189
|
+
echo -n "(HTTP ${HTTP_CODE}, retry in ${WAIT_SECONDS}s) "
|
|
190
|
+
rm -f "$RESP_HEADERS_FILE"
|
|
191
|
+
sleep "$WAIT_SECONDS"
|
|
192
|
+
ATTEMPT=$((ATTEMPT + 1))
|
|
193
|
+
BACKOFF=$((BACKOFF * 2))
|
|
194
|
+
continue
|
|
195
|
+
fi
|
|
196
|
+
fi
|
|
197
|
+
rm -f "$RESP_HEADERS_FILE"
|
|
198
|
+
break
|
|
199
|
+
done
|
|
200
|
+
|
|
201
|
+
if [ "$HTTP_CODE" -ge 200 ] && [ "$HTTP_CODE" -lt 300 ]; then
|
|
202
|
+
rm -f "$RESP_BODY_FILE"
|
|
203
|
+
if [ "$ATTEMPT" -gt 1 ]; then
|
|
204
|
+
echo "OK (${FILE_SIZE} bytes, attempt ${ATTEMPT}/${MAX_ATTEMPTS})"
|
|
205
|
+
else
|
|
206
|
+
echo "OK (${FILE_SIZE} bytes)"
|
|
207
|
+
fi
|
|
208
|
+
SUCCEEDED=$((SUCCEEDED + 1))
|
|
209
|
+
TOTAL_SIZE=$((TOTAL_SIZE + FILE_SIZE))
|
|
210
|
+
else
|
|
211
|
+
echo "FAILED (HTTP ${HTTP_CODE} after ${ATTEMPT} attempt(s))"
|
|
212
|
+
echo " Response: $(head -c 500 "$RESP_BODY_FILE")"
|
|
213
|
+
rm -f "$RESP_BODY_FILE"
|
|
214
|
+
FAILED=$((FAILED + 1))
|
|
215
|
+
fi
|
|
216
|
+
done
|
|
217
|
+
|
|
218
|
+
# --- Summary ---
|
|
219
|
+
echo ""
|
|
220
|
+
echo "=== Upload Summary ==="
|
|
221
|
+
echo "Files: ${SUCCEEDED} succeeded, ${FAILED} failed (${#FILES[@]} total)"
|
|
222
|
+
echo "Total size: $((TOTAL_SIZE / 1024)) KB"
|
|
223
|
+
if [ "$FAILED" -gt 0 ]; then
|
|
224
|
+
exit 1
|
|
225
|
+
fi
|
package/sdlc/CLAUDE.md
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
4
|
+
|
|
5
|
+
## What This Repository Is
|
|
6
|
+
|
|
7
|
+
This is a compliance-grade SDLC template system — a set of 12 documents across two tiers that implement a workflow-driven development pipeline satisfying ISO 29119, ISO 27001, GDPR, SOC 2, and EU AI Act requirements. It is not a software application; it contains markdown templates and an accompanying article.
|
|
8
|
+
|
|
9
|
+
## Repository Structure
|
|
10
|
+
|
|
11
|
+
- `article.md` — Long-form article explaining the system's design and rationale
|
|
12
|
+
- `files/` — The 12 template documents:
|
|
13
|
+
- **Tier 1 (universal, never project-specific):** `Test_Policy.md`, `Test_Strategy.md`, `Test_Architecture.md`, `Periodic_Security_Review_Schedule.md`
|
|
14
|
+
- **Tier 2 (project-specific, customized per project):** `0-project-setup.md` through `5-deploy-main.md` (workflows), `Test_Plan_TEMPLATE.md`, `README_TEMPLATE.md`
|
|
15
|
+
|
|
16
|
+
## Key Design Principles
|
|
17
|
+
|
|
18
|
+
- **Single responsibility per document.** Policy says _what_ and _why_, Strategy says _how methodically_, Architecture says _with what tools_. No content should appear in two places.
|
|
19
|
+
- **Tier 1 never references a specific project.** Tools are referenced by category in Policy/Strategy; only Architecture names specific products and versions.
|
|
20
|
+
- **Risk-based proportionality.** Documentation, testing depth, and review requirements scale with risk level (Low/Medium/High). AI involvement raises risk by one level for Medium/High categories.
|
|
21
|
+
- **Workflow-driven compliance.** The six workflows (0-5) are executable procedures with specific commands, not guidelines. Compliance artifacts are natural outputs of following the workflows.
|
|
22
|
+
|
|
23
|
+
## Development Model: Developer + AI Partner
|
|
24
|
+
|
|
25
|
+
Each project follows a **single owner-developer partnered with AI coding agents** model:
|
|
26
|
+
|
|
27
|
+
- **Owner-developer** provides direction, judgment, and approval. They are accountable for the project.
|
|
28
|
+
- **AI agent** (Claude Code, Windsurf, Cursor) acts as implementation partner, compliance enforcer, and reviewer. The SDLC process is enforced by the AI on every code change via drop-in rules (`sdlc/ai-rules/`).
|
|
29
|
+
- **Branching is trunk-based** with a permanent `develop` branch — no feature branches. Parallel work is handled by the AI within a single stream, not by multiple developers on separate branches.
|
|
30
|
+
- **PR reviews** are owner-reviewed with AI-assisted verification. CI provides independent, tamper-resistant evidence. The SDLC workflows and compliance gates replace traditional team ceremonies (standups, sprint planning).
|
|
31
|
+
- **The AI is the second pair of eyes.** It asks which requirement a change is for, blocks implementation until planning is complete, enforces commit conventions, runs compliance gates, and guides evidence compilation.
|
|
32
|
+
|
|
33
|
+
## Workflow Sequence
|
|
34
|
+
|
|
35
|
+
0. **Project Setup** (run once) — repo, branches, CI, compliance directories
|
|
36
|
+
1. **Plan Requirement** — define in RTM, classify risk, generate test scope _before_ implementation
|
|
37
|
+
2. **Implement and Test** — code on `develop`, all local gates green on every commit
|
|
38
|
+
3. **Compile Evidence** — gather artifacts, create release ticket, update RTM
|
|
39
|
+
4. **Submit for Review** — PR triggers independent CI verification + human review
|
|
40
|
+
5. **Deploy to Main** — merge, verify deployment, finalize compliance artifacts
|
|
41
|
+
|
|
42
|
+
## Mandatory Gates
|
|
43
|
+
|
|
44
|
+
All templates assume these gates: TypeScript (0 errors), SAST/Semgrep (0 high/critical), dependency audit (0 high/critical), E2E tests (all pass), human PR approval.
|
|
45
|
+
|
|
46
|
+
## Conventions in Templates
|
|
47
|
+
|
|
48
|
+
- **Commit format:** Conventional Commits with `Co-Authored-By` tags for AI, `Ref: REQ-XXX` for tracked requirements
|
|
49
|
+
- **Requirement IDs:** `REQ-XXX` format, tracked in `compliance/RTM.md`
|
|
50
|
+
- **Status lifecycle:** DRAFT → IN PROGRESS → TESTED - PENDING SIGN-OFF → APPROVED - DEPLOYED
|
|
51
|
+
- **Branching:** permanent `develop` branch, protected `main` (production), merge commits to preserve audit trail
|
|
52
|
+
- **Evidence model:** local testing (comprehensive) + CI testing (independent verification, tamper-resistant)
|
|
53
|
+
- **Placeholders:** Templates use `[BRACKETED_VALUES]` and `# UPDATE` markers for project-specific customization
|
|
54
|
+
|
|
55
|
+
## When Editing These Templates
|
|
56
|
+
|
|
57
|
+
- Maintain the separation between Tier 1 and Tier 2 — if content applies universally, it belongs in Tier 1; if project-specific, Tier 2.
|
|
58
|
+
- Keep workflow documents as executable procedures with concrete commands, not abstract guidance.
|
|
59
|
+
- Risk classification rules and AI governance controls are defined in Test_Policy.md and Test_Strategy.md — don't duplicate them in workflow files.
|
|
60
|
+
- The article (`article.md`) should stay consistent with the templates; if you change a process in a template, check whether the article describes the old process.
|
|
61
|
+
|
|
62
|
+
## Syncing Templates to Consuming Projects
|
|
63
|
+
|
|
64
|
+
After updating SDLC templates, sync to consuming projects:
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
# Pass one path per active consumer. Only WGB is live as of 2026-05-19.
|
|
68
|
+
devaudit update v1.x.0 ../wawagardenbar-app
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
This tags DevAudit, copies all templates (workflow files, AI rules, hooks, scripts, CI templates), and updates tag references in the consuming project's CI workflows. Review the diff in each project before committing.
|
|
72
|
+
|
|
73
|
+
META-AGENT / META-ATS / META-JOBS onboarding attempts were reverted (see [docs/consuming-projects.md](../docs/consuming-projects.md)); pass their paths to the same command if and when they return as live consumers.
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
# Host adapter contract
|
|
2
|
+
|
|
3
|
+
A host adapter teaches the Metasession SDLC how to deploy and verify on one platform — `railway`, `vercel`, `fly`, `kubernetes`, `self-hosted-docker`, etc. Each adapter is a single directory under `sdlc/files/hosts/` containing:
|
|
4
|
+
|
|
5
|
+
```
|
|
6
|
+
sdlc/files/hosts/<name>/
|
|
7
|
+
└── adapter.json ← the manifest (validated against the schema)
|
|
8
|
+
```
|
|
9
|
+
|
|
10
|
+
Hosts don't usually bring their own hooks or scripts the way stacks do — the host's contribution is the deploy trigger, the URL-resolution scheme, and the wait/verify snippet that lands inside the post-deploy workflow template. So most host adapters are just a manifest.
|
|
11
|
+
|
|
12
|
+
The schema lives at [`sdlc/files/hosts/_schema/adapter.schema.json`](./files/hosts/_schema/adapter.schema.json) (JSON Schema draft-07). The validator is `scripts/validate-adapter.cjs`; CI runs `node scripts/validate-adapter.cjs --all` on every push to `develop` and validates both stack and host adapters at once.
|
|
13
|
+
|
|
14
|
+
## Required fields
|
|
15
|
+
|
|
16
|
+
### Identity
|
|
17
|
+
|
|
18
|
+
| Field | Type | Purpose |
|
|
19
|
+
| ------------- | ---------------------------------- | ------------------------------------------------------------------------------------------- |
|
|
20
|
+
| `name` | string (`[a-z0-9][a-z0-9-]{0,31}`) | Identifier matching the parent directory and the `host` key in consumer `sdlc-config.json`. |
|
|
21
|
+
| `description` | string | One-line human summary of the platform and how it deploys. |
|
|
22
|
+
|
|
23
|
+
### Deploy trigger
|
|
24
|
+
|
|
25
|
+
| Field | Type | Purpose |
|
|
26
|
+
| ---------------- | ----------------------------------------------------- | ----------------------------------- |
|
|
27
|
+
| `deploy_trigger` | enum (`push_to_main`, `git_tag`, `manual`, `ci_step`) | What kicks off a production deploy. |
|
|
28
|
+
|
|
29
|
+
- `push_to_main` — Railway, Vercel default. The platform watches the repo and deploys whenever `main` changes. No explicit deploy step in CI.
|
|
30
|
+
- `git_tag` — Some setups deploy on tag push, not on every commit to main.
|
|
31
|
+
- `manual` — Operator clicks "deploy" in the platform's UI. CI doesn't trigger anything.
|
|
32
|
+
- `ci_step` — The CI workflow runs an explicit deploy command (`flyctl deploy`, `kubectl rollout`, `docker compose up`).
|
|
33
|
+
|
|
34
|
+
### Production URL resolution
|
|
35
|
+
|
|
36
|
+
The post-deploy workflow needs to know **the URL** of the just-deployed production service so it can run smoke tests and record evidence.
|
|
37
|
+
|
|
38
|
+
| Field | Type | Purpose |
|
|
39
|
+
| --------------------------- | ---------------------------------------------- | ------------------------------------------------------------------------------------------------------------------ |
|
|
40
|
+
| `production_url_from` | enum (`secret`, `static`, `api_lookup`, `env`) | Where the URL comes from. |
|
|
41
|
+
| `production_url_secret_key` | string (when `production_url_from = secret`) | The `sdlc-config.json` key whose value names the GitHub Secret holding the URL. Typically `production_url_secret`. |
|
|
42
|
+
| `production_url_static` | string (when `production_url_from = static`) | The literal URL (or template). |
|
|
43
|
+
|
|
44
|
+
- `secret` — URL stored as a GitHub Secret per-consumer. Most flexible; right when each project deploys to a different URL.
|
|
45
|
+
- `static` — URL hardcoded in the adapter. Right when all consumers on this host share a fixed URL pattern (rare).
|
|
46
|
+
- `api_lookup` — Adapter ships a snippet that resolves the URL by calling the host's API (e.g. `flyctl status --json`). Right when the URL is auto-generated and changes per deploy.
|
|
47
|
+
- `env` — URL is set as a workflow env var from elsewhere in the consumer's CI. Right for self-hosted setups that already know the URL out-of-band.
|
|
48
|
+
|
|
49
|
+
The schema enforces that `production_url_secret_key` is present iff `production_url_from = secret`, and same for `static`.
|
|
50
|
+
|
|
51
|
+
## Optional fields
|
|
52
|
+
|
|
53
|
+
### Wait and post-deploy
|
|
54
|
+
|
|
55
|
+
| Field | Type | Purpose |
|
|
56
|
+
| ------------------ | ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
57
|
+
| `wait_for_deploy` | string (shell snippet) | Blocks until the deploy is live and healthy. Embedded into `post-deploy-prod.yml.template` at sync time. Omit for hosts where deploy is synchronous. |
|
|
58
|
+
| `post_deploy_hook` | string (shell snippet) | Runs after a successful deploy — cache warmup, host-specific bookkeeping, additional smoke tests. |
|
|
59
|
+
|
|
60
|
+
Both snippets run in a `bash -e` step; they can reference `${PROD_URL}` and any `required_env` values.
|
|
61
|
+
|
|
62
|
+
### Required secrets and env
|
|
63
|
+
|
|
64
|
+
| Field | Type | Purpose |
|
|
65
|
+
| ------------------ | -------- | ---------------------------------------------------------------------------------------------------------------------- |
|
|
66
|
+
| `required_secrets` | string[] | GitHub Secrets the adapter expects to be set on the consumer repo. CI workflows fail at runtime if these are missing. |
|
|
67
|
+
| `required_env` | string[] | Non-sensitive identifiers (app names, region IDs) the consumer must set — typically populated from `sdlc-config.json`. |
|
|
68
|
+
|
|
69
|
+
Sync may warn if these are absent; it's a soft check (the CI workflow is the hard check, since the script can't authenticate to the host on the dev's behalf).
|
|
70
|
+
|
|
71
|
+
### sdlc-config.json keys
|
|
72
|
+
|
|
73
|
+
| Field | Type | Purpose |
|
|
74
|
+
| ---------------------- | -------- | -------------------------------------------------------------- |
|
|
75
|
+
| `config_keys.required` | string[] | Keys consumers must define. |
|
|
76
|
+
| `config_keys.optional` | string[] | Keys consumers may define (e.g. an optional database service). |
|
|
77
|
+
| `config_keys.defaults` | object | Fallback values when a key is absent. |
|
|
78
|
+
|
|
79
|
+
### Notes
|
|
80
|
+
|
|
81
|
+
| Field | Type | Purpose |
|
|
82
|
+
| ------- | -------- | ------------------------------------------------------------------------------------------------------------------------------- |
|
|
83
|
+
| `notes` | string[] | Free-form notes about the host's quirks. Backed up here so future maintainers don't rediscover them. Not consumed by templates. |
|
|
84
|
+
|
|
85
|
+
## Adding a new host
|
|
86
|
+
|
|
87
|
+
See the step-by-step walkthrough: **[docs/adding-a-host.md](../docs/adding-a-host.md)** — uses Fly.io as the worked example. The high-level shape is:
|
|
88
|
+
|
|
89
|
+
1. **Create the directory** `sdlc/files/hosts/<name>/`.
|
|
90
|
+
2. **Author `adapter.json`** with every required field. Use `hosts/railway/adapter.json` as a worked example.
|
|
91
|
+
3. **Run the validator:** `node scripts/validate-adapter.cjs sdlc/files/hosts/<name>/adapter.json`. Fix any errors.
|
|
92
|
+
4. **Validate against a real consumer** before merging — at least one project on this host should sync cleanly and reach `released` end-to-end. A host adapter validated only against `examples/` isn't load-bearing.
|
|
93
|
+
|
|
94
|
+
## Worked example: Fly.io
|
|
95
|
+
|
|
96
|
+
```json
|
|
97
|
+
{
|
|
98
|
+
"$schema": "../_schema/adapter.schema.json",
|
|
99
|
+
"name": "fly",
|
|
100
|
+
"description": "Fly.io-hosted services. CI runs `flyctl deploy` explicitly; production URL discovered via the Fly API.",
|
|
101
|
+
"deploy_trigger": "ci_step",
|
|
102
|
+
"production_url_from": "api_lookup",
|
|
103
|
+
"wait_for_deploy": "for i in $(seq 1 30); do flyctl status --app \"${APP_NAME}\" --json | jq -e '.Deployment.Status == \"successful\"' && break; sleep 10; done",
|
|
104
|
+
"required_secrets": ["FLY_API_TOKEN", "DEVAUDIT_API_KEY"],
|
|
105
|
+
"required_env": ["APP_NAME"],
|
|
106
|
+
"notes": [
|
|
107
|
+
"Production URL is resolved at deploy time by flyctl — no GitHub Secret to maintain.",
|
|
108
|
+
"Deploy step runs `flyctl deploy --remote-only` in the post-deploy workflow; FLY_API_TOKEN is the auth."
|
|
109
|
+
]
|
|
110
|
+
}
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
This adapter isn't shipped yet — listed here as a sketch of what a non-Railway host adapter looks like.
|
|
114
|
+
|
|
115
|
+
## Why JSON Schema
|
|
116
|
+
|
|
117
|
+
Same reasons as [STACK_ADAPTER.md](./STACK_ADAPTER.md#why-json-schema-not-zod-not-a-typescript-interface): IDE tooling, language-neutrality, stable versioned artifact. The validator script is the same one stacks use — auto-detects the type from path and applies the matching schema.
|
|
118
|
+
|
|
119
|
+
## Evolution
|
|
120
|
+
|
|
121
|
+
Backward-compatible additions (new optional fields) need:
|
|
122
|
+
|
|
123
|
+
1. Schema update.
|
|
124
|
+
2. This doc updated.
|
|
125
|
+
3. Existing adapters can stay as they are.
|
|
126
|
+
|
|
127
|
+
Backward-incompatible changes (renaming or removing required fields, narrowing an enum) need a v1.24.0-level version bump and a migration note for consumers.
|
package/sdlc/SKILLS.md
ADDED
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
# SDLC Skills — contract and conventions
|
|
2
|
+
|
|
3
|
+
The Metasession SDLC framework ships **Claude Code Skills** alongside its stage docs, adapters, and CI templates. Skills are self-contained behaviour packs the AI agent invokes when it recognises a relevant trigger — "add e2e tests for [ticket]", "classify the risk tier of this REQ", "triage these SAST findings". They specialise within stages (the stage doc owns _when and why_; the skill owns _how_).
|
|
4
|
+
|
|
5
|
+
This document is the contract every framework-shipped skill must follow. For the walkthrough on adding a new skill, see [docs/adding-a-skill.md](../docs/adding-a-skill.md). For the architectural rationale on the framework's layered design, see [ADR-001](../docs/ADR/ADR-001-polyglot-sdlc-architecture.md).
|
|
6
|
+
|
|
7
|
+
## Where skills live
|
|
8
|
+
|
|
9
|
+
Same layering as adapters:
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
sdlc/files/
|
|
13
|
+
├── _common/
|
|
14
|
+
│ └── skills/ ← universal skills (stack-agnostic)
|
|
15
|
+
│ ├── _schema/skill.schema.json ← frontmatter schema
|
|
16
|
+
│ └── <skill-name>/
|
|
17
|
+
│ ├── SKILL.md ← required: frontmatter + instructions
|
|
18
|
+
│ └── references/ ← optional: longer docs the skill links to
|
|
19
|
+
└── stacks/
|
|
20
|
+
├── node/
|
|
21
|
+
│ └── skills/ ← node-only skills (when needed)
|
|
22
|
+
└── python/
|
|
23
|
+
└── skills/ ← python-only skills (when needed)
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
A skill is `_common/` when its body is genuinely framework-agnostic (auto-detects toolchain, doesn't depend on a single ecosystem). It's stack-scoped when its instructions assume a specific package manager, test framework, or build tool that other stacks don't share.
|
|
27
|
+
|
|
28
|
+
## How skills reach consumers
|
|
29
|
+
|
|
30
|
+
`devaudit update` (cli/src/update/skills.ts) copies every skill directory into the consumer's `.claude/skills/<skill-name>/` on every sync:
|
|
31
|
+
|
|
32
|
+
- All `_common/skills/<name>/` directories sync to every consumer.
|
|
33
|
+
- `stacks/<stack>/skills/<name>/` directories sync only when the consumer's `sdlc-config.json` selects that stack.
|
|
34
|
+
- The `_schema/` directory (and any other `_`-prefixed directory) is **not** synced — schemas are framework infrastructure.
|
|
35
|
+
|
|
36
|
+
Claude Code reads `.claude/skills/*/SKILL.md` for discovery; once synced, the skill is immediately available to the consumer's AI agent without further configuration.
|
|
37
|
+
|
|
38
|
+
Other AI tools (Cursor, Windsurf, Gemini CLI) don't have a native Skill mechanism. The skill content is referenced from `INSTRUCTIONS.md` so non-Claude agents can still consume it manually — they don't auto-invoke based on `description` triggers, but the content is reachable.
|
|
39
|
+
|
|
40
|
+
### Additional emissions
|
|
41
|
+
|
|
42
|
+
A skill is allowed to ship code that the consumer's test/build tooling needs to `import` at runtime — a helper, a fixture, a shared utility. The canonical source lives under the skill's `references/` directory (so it's discoverable alongside the SKILL.md that teaches its use), and `devaudit update` emits a copy into the right place in the consumer's source tree.
|
|
43
|
+
|
|
44
|
+
Currently the only such emission is the e2e-test-engineer skill's `evidence.ts` helper, which syncs to `<consumer>/e2e/helpers/evidence.ts` on node-stack consumers. The pattern: add a guarded section to the CLI skill sync (`cli/src/update/skills.ts`) — the skill's main bundle still syncs to `.claude/skills/` as normal, but the extra file lands where the consumer's tests can import it.
|
|
45
|
+
|
|
46
|
+
Use this pattern sparingly. If the skill only needs to teach a concept, a Markdown example in SKILL.md is enough. If the skill prescribes a helper consumers must call from their own code, that helper deserves to be canonical and shipped — not copy-pasted from a doc.
|
|
47
|
+
|
|
48
|
+
## SKILL.md frontmatter contract
|
|
49
|
+
|
|
50
|
+
Required fields:
|
|
51
|
+
|
|
52
|
+
| Field | Type | Constraint | Purpose |
|
|
53
|
+
| ------------- | ------ | --------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
54
|
+
| `name` | string | `^[a-z0-9][a-z0-9-]{1,63}$` | Identifier matching the parent directory. How Claude refers to the skill when reporting which one fired. |
|
|
55
|
+
| `description` | string | minLength 50 | What the skill does **and** when to invoke it. The "when" half drives discovery — without trigger phrases, the skill never fires. Aim for 100–500 chars. |
|
|
56
|
+
|
|
57
|
+
Optional fields:
|
|
58
|
+
|
|
59
|
+
| Field | Type | Purpose |
|
|
60
|
+
| --------- | -------- | ------------------------------------------------------------------------------------------ |
|
|
61
|
+
| `version` | string | Semver. Useful when a skill's behaviour changes incompatibly so consumers can pin. |
|
|
62
|
+
| `tags` | string[] | Documentation grouping (e.g. `testing`, `security`, `compliance`). Not consumed by Claude. |
|
|
63
|
+
| `license` | string | SPDX identifier or `proprietary`. |
|
|
64
|
+
|
|
65
|
+
`additionalProperties: false` — new fields require a deliberate schema update first.
|
|
66
|
+
|
|
67
|
+
The body of SKILL.md (everything after the closing `---`) is free-form Markdown. Claude reads it as the skill's instructions. Conventions worth following:
|
|
68
|
+
|
|
69
|
+
- Open with a one-paragraph summary of what the skill does.
|
|
70
|
+
- A **Scope** section: in-scope and out-of-scope behaviours.
|
|
71
|
+
- A **Workflow** section: numbered phases the skill walks through. Each phase should be self-contained enough that re-entering mid-skill is sensible.
|
|
72
|
+
- **Principles** at the end: cross-cutting rules the skill never violates (e.g. "never delete tests without explicit confirmation").
|
|
73
|
+
|
|
74
|
+
## How to write a good `description`
|
|
75
|
+
|
|
76
|
+
This is the load-bearing field. Bad descriptions lead to "the skill never fires" or "the skill fires constantly on irrelevant requests". Aim for:
|
|
77
|
+
|
|
78
|
+
1. **What the skill does**, in one clause. _"Maintain or bootstrap a project's end-to-end and visual regression test pack."_
|
|
79
|
+
2. **When to invoke it.** Both natural-language phrasings and concrete triggers. _"Use when the user wants to add, update, or retire e2e or visual tests for a feature, ticket, issue, or PR."_ Then list explicit trigger phrases: _"Trigger on phrases like 'add e2e tests for [ticket]', 'update the test pack', 'what tests do we need for this issue'…"_
|
|
80
|
+
3. **When NOT to invoke.** Explicit out-of-scope rules. _"Do NOT use for unit, component, or API-only tests, or performance tests."_
|
|
81
|
+
|
|
82
|
+
If a contributor reads only the description and gets the right invocation pattern, the description is doing its job.
|
|
83
|
+
|
|
84
|
+
## Validation
|
|
85
|
+
|
|
86
|
+
CI runs `node scripts/validate-adapter.cjs --all` on every push to develop. The validator parses the YAML frontmatter at the top of every `SKILL.md` and validates against `sdlc/files/_common/skills/_schema/skill.schema.json`. Errors are reported with the offending field path.
|
|
87
|
+
|
|
88
|
+
To validate a single skill locally:
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
node scripts/validate-adapter.cjs sdlc/files/_common/skills/<name>/SKILL.md
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## Skills currently shipped
|
|
95
|
+
|
|
96
|
+
| Skill | Location | Triggers (paraphrased) | Additional emissions |
|
|
97
|
+
| ------------------- | ----------------- | ---------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------ |
|
|
98
|
+
| `e2e-test-engineer` | `_common/skills/` | "add e2e tests", "bootstrap an e2e suite", "update the test pack", "are any tests obsolete", "run e2e tests and file issues" | `e2e/helpers/evidence.ts` (node-stack consumers) |
|
|
99
|
+
|
|
100
|
+
## Skills on the roadmap
|
|
101
|
+
|
|
102
|
+
| Candidate skill | Likely trigger surface | Supports SDLC stage |
|
|
103
|
+
| ------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | ------------------- |
|
|
104
|
+
| `sdlc-implementer` | "implement issue #N under the SDLC", "run the SDLC for issue #N", "automate REQ-XXX from issue to release", "do the SDLC for [issue]" | All stages (1–5) |
|
|
105
|
+
|
|
106
|
+
`sdlc-implementer` is an **orchestration skill** — it drives Claude Code's native tools (`gh`, shell, `devaudit` CLI, portal API) through the full 5-stage flow against a single GitHub issue, pausing only at the UAT-review gate (and at the plan checkpoint for HIGH/CRITICAL risk). It replaces an earlier roadmap of five atomic skills (`risk-classifier`, `commit-message-author`, `compliance-evidence-author`, `sast-triager`, `release-ticket-author`) that were deprioritised — Claude Code's innate capabilities already cover what those atomic skills wrapped; the value-add is end-to-end orchestration with framework-compliant pauses, not five discoverable helpers a human still has to compose.
|
|
107
|
+
|
|
108
|
+
**Current status.** SKILL.md + 3 references files are authored at [`sdlc/files/_common/skills/sdlc-implementer/`](./files/_common/skills/sdlc-implementer/) on `main` (Phase B, PR #31). Validator passes. Phase C — smoke against `wawagardenbar-app` — is the last step before this row moves to "Skills currently shipped" above.
|
|
109
|
+
|
|
110
|
+
**Sub-skill invocation requirement.** During its Phase 2 (Implement & test), the orchestrator **MUST** invoke `e2e-test-engineer` for any end-to-end or visual-regression test work — both scenario derivation from the implementation plan and execution of the resulting suite. The orchestrator does NOT author e2e tests directly. (Unit tests stay with the orchestrator until a unit-test counterpart skill ships.) The invocation pattern is documented in [docs/adding-a-skill.md §Orchestrator skills](../docs/adding-a-skill.md#orchestrator-skills-calling-other-skills); this is a hard contract — the orchestrator's SKILL.md fails review if it inlines `e2e-test-engineer`'s procedure.
|
|
111
|
+
|
|
112
|
+
Tracking: [`metasession-dev/DevAudit-Installer#29`](https://github.com/metasession-dev/DevAudit-Installer/issues/29) (umbrella).
|
|
113
|
+
|
|
114
|
+
Other speculative skills land when a real driver appears (a project's day-to-day work surfaces the same pain repeatedly and the orchestrator's internals demonstrably need it as a separable component).
|
|
115
|
+
|
|
116
|
+
## When to make a skill vs. when to keep something in a stage doc
|
|
117
|
+
|
|
118
|
+
Three rules of thumb:
|
|
119
|
+
|
|
120
|
+
1. **Stage docs own _when_ and _why_.** "After Stage 2 implementation, before Stage 3 evidence compilation, the team should…" — that's stage-doc material, not skill material.
|
|
121
|
+
2. **Skills own _how_.** Multi-step procedures that are reusable across requirements, opinionated about technique, and benefit from being invoked by a discovery-trigger phrase belong in skills.
|
|
122
|
+
3. **If two stage docs would each instruct the AI to do the same multi-step procedure, lift it into a skill.** Both Stage 2 ("update tests") and Stage 3 ("re-run the suite, file defects") need the same e2e-test-engineering procedure. Lifting that into a skill keeps the stage docs focused on flow and avoids drift.
|
|
123
|
+
|
|
124
|
+
## Evolution
|
|
125
|
+
|
|
126
|
+
Backward-compatible additions to the frontmatter (new optional fields): update the schema first, then the docs, then the skills can adopt the new field.
|
|
127
|
+
|
|
128
|
+
Renaming or removing a required field is a v1.next-major change with a deprecation cycle (mirror `working_directory` rollout: warn for one minor version, refuse in the next).
|
|
129
|
+
|
|
130
|
+
When a skill's behaviour changes meaningfully, bump its `version`. Consumers pinning to an old version can re-sync at their own pace.
|
|
131
|
+
|
|
132
|
+
## See also
|
|
133
|
+
|
|
134
|
+
- [docs/adding-a-skill.md](../docs/adding-a-skill.md) — walkthrough for authoring a new skill.
|
|
135
|
+
- [STACK_ADAPTER.md](./STACK_ADAPTER.md) / [HOST_ADAPTER.md](./HOST_ADAPTER.md) — sibling contracts for the adapter layers.
|
|
136
|
+
- [ADR-001](../docs/ADR/ADR-001-polyglot-sdlc-architecture.md) — why the framework is layered this way.
|
|
137
|
+
- [Anthropic's Claude Code Skills docs](https://docs.claude.com/en/docs/claude-code/skills) — upstream format reference.
|