@metasession.co/devaudit-cli 0.3.9 → 0.3.11
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/dist/index.js +70 -22
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/sdlc/HOST_ADAPTER.md +17 -0
- package/sdlc/SKILLS.md +8 -0
- package/sdlc/files/_common/joining-an-existing-project.md +5 -4
- package/sdlc/files/_common/scripts/close-out-contract.test.sh +71 -0
- package/sdlc/files/_common/scripts/prepare-release-pr.sh +99 -0
- package/sdlc/files/_common/scripts/validate-commits.sh +32 -7
- package/sdlc/files/_common/scripts/validate-commits.test.sh +143 -0
- package/sdlc/files/_common/skills/sdlc-implementer/SKILL.md +39 -3
- package/sdlc/files/ci/ci-status-fallback.yml.template +4 -0
- package/sdlc/files/ci/ci.yml.template +2 -2
- package/sdlc/files/ci/compliance-evidence.yml.template +49 -4
- package/sdlc/files/ci/incident-export.yml.template +7 -3
- package/sdlc/files/ci/label-retention.yml.template +3 -1
- package/sdlc/files/ci/periodic-review.yml.template +5 -3
- package/sdlc/files/ci/post-deploy-prod.yml.template +6 -1
- package/sdlc/files/ci/quality-gates-provenance.yml.template +1 -1
- package/sdlc/files/hosts/_schema/adapter.schema.json +31 -0
- package/sdlc/files/hosts/railway/adapter.json +8 -1
- package/sdlc/files/stacks/node/hooks/pre-push +13 -13
- package/sdlc/package.json +1 -1
- package/sdlc/src/bin/devaudit-sdlc.js +490 -54
|
@@ -49,7 +49,9 @@ jobs:
|
|
|
49
49
|
- uses: actions/checkout@v6
|
|
50
50
|
with:
|
|
51
51
|
fetch-depth: 0
|
|
52
|
-
|
|
52
|
+
# GitHub repo mutations use the workflow token. The DevAudit
|
|
53
|
+
# user token is for portal attribution, not GitHub checkout/push.
|
|
54
|
+
token: ${{ github.token }}
|
|
53
55
|
|
|
54
56
|
- name: Classify routing (Path A vs Path B)
|
|
55
57
|
id: route
|
|
@@ -436,7 +438,8 @@ jobs:
|
|
|
436
438
|
- name: Direct commit to develop (Path A)
|
|
437
439
|
if: steps.route.outputs.path == 'A'
|
|
438
440
|
env:
|
|
439
|
-
|
|
441
|
+
# GitHub push uses the workflow token plus job permissions.
|
|
442
|
+
GH_TOKEN: ${{ github.token }}
|
|
440
443
|
OUT: ${{ steps.paths.outputs.out }}
|
|
441
444
|
ISSUE_NUMBER: ${{ github.event.issue.number }}
|
|
442
445
|
ISSUE_URL: ${{ github.event.issue.html_url }}
|
|
@@ -454,7 +457,8 @@ jobs:
|
|
|
454
457
|
- name: Open export PR (Path B)
|
|
455
458
|
if: steps.route.outputs.path == 'B'
|
|
456
459
|
env:
|
|
457
|
-
|
|
460
|
+
# GitHub branch push + PR creation use the workflow token.
|
|
461
|
+
GH_TOKEN: ${{ github.token }}
|
|
458
462
|
BRANCH: ${{ steps.paths.outputs.branch }}
|
|
459
463
|
OUT: ${{ steps.paths.outputs.out }}
|
|
460
464
|
ISSUE_NUMBER: ${{ github.event.issue.number }}
|
|
@@ -56,7 +56,9 @@ jobs:
|
|
|
56
56
|
- name: Enforce label retention
|
|
57
57
|
if: steps.opt.outputs.enabled == 'true'
|
|
58
58
|
env:
|
|
59
|
-
|
|
59
|
+
# GitHub issue/comment mutations use the workflow token. The
|
|
60
|
+
# DevAudit user token is reserved for portal attribution flows.
|
|
61
|
+
GH_TOKEN: ${{ github.token }}
|
|
60
62
|
EVENT_NAME: ${{ github.event_name }}
|
|
61
63
|
EVENT_ACTION: ${{ github.event.action }}
|
|
62
64
|
ISSUE_NUMBER: ${{ github.event.issue.number }}
|
|
@@ -37,8 +37,9 @@ jobs:
|
|
|
37
37
|
- uses: actions/checkout@v6
|
|
38
38
|
with:
|
|
39
39
|
fetch-depth: 0
|
|
40
|
-
# Need write access for the chore branch.
|
|
41
|
-
token
|
|
40
|
+
# Need write access for the chore branch. GitHub repo mutations
|
|
41
|
+
# use the workflow token; the DevAudit user token is portal auth.
|
|
42
|
+
token: ${{ github.token }}
|
|
42
43
|
|
|
43
44
|
- name: Compute review period
|
|
44
45
|
id: period
|
|
@@ -188,7 +189,8 @@ jobs:
|
|
|
188
189
|
|
|
189
190
|
- name: Open / update review PR
|
|
190
191
|
env:
|
|
191
|
-
|
|
192
|
+
# GitHub branch push + PR creation use the workflow token.
|
|
193
|
+
GH_TOKEN: ${{ github.token }}
|
|
192
194
|
BRANCH: ${{ steps.period.outputs.branch }}
|
|
193
195
|
REVIEW_ID: ${{ steps.period.outputs.review_id }}
|
|
194
196
|
run: |
|
|
@@ -34,6 +34,9 @@ jobs:
|
|
|
34
34
|
production-evidence:
|
|
35
35
|
name: Production Evidence
|
|
36
36
|
runs-on: {{RUNNER}}
|
|
37
|
+
permissions:
|
|
38
|
+
contents: read
|
|
39
|
+
issues: write
|
|
37
40
|
env:
|
|
38
41
|
DEVAUDIT_BASE_URL_VAR: ${{ vars.DEVAUDIT_BASE_URL }}
|
|
39
42
|
DEVAUDIT_API_KEY: ${{ secrets.DEVAUDIT_API_KEY }}
|
|
@@ -151,7 +154,9 @@ jobs:
|
|
|
151
154
|
- name: File incident on smoke failure
|
|
152
155
|
if: failure()
|
|
153
156
|
env:
|
|
154
|
-
|
|
157
|
+
# GitHub issue/label mutations use the workflow token. DevAudit
|
|
158
|
+
# user tokens are portal PATs, not guaranteed GitHub PATs (#305).
|
|
159
|
+
GH_TOKEN: ${{ github.token }}
|
|
155
160
|
PROD_URL: ${{ secrets.{{PRODUCTION_URL_SECRET}} }}
|
|
156
161
|
GIT_SHA: ${{ github.sha }}
|
|
157
162
|
CI_RUN: ${{ github.run_id }}
|
|
@@ -31,7 +31,7 @@ jobs:
|
|
|
31
31
|
steps:
|
|
32
32
|
- name: Verify prior Quality Gates success on head SHA
|
|
33
33
|
env:
|
|
34
|
-
GH_TOKEN: ${{
|
|
34
|
+
GH_TOKEN: ${{ github.token }}
|
|
35
35
|
HEAD_SHA: ${{ github.event.pull_request.head.sha }}
|
|
36
36
|
CURRENT_RUN_ID: ${{ github.run_id }}
|
|
37
37
|
run: |
|
|
@@ -84,6 +84,37 @@
|
|
|
84
84
|
},
|
|
85
85
|
"description": "sdlc-config.json keys this host adapter consumes. `required` keys must be present; `optional` are tolerated; `defaults` provides fallback values."
|
|
86
86
|
},
|
|
87
|
+
"runtime_contract": {
|
|
88
|
+
"type": "object",
|
|
89
|
+
"additionalProperties": false,
|
|
90
|
+
"required": [
|
|
91
|
+
"preferred_web_runtime",
|
|
92
|
+
"forbid_typescript_runtime",
|
|
93
|
+
"prefer_standalone_output",
|
|
94
|
+
"scheduler_placement"
|
|
95
|
+
],
|
|
96
|
+
"properties": {
|
|
97
|
+
"preferred_web_runtime": {
|
|
98
|
+
"type": "string",
|
|
99
|
+
"minLength": 1,
|
|
100
|
+
"description": "Operator-facing guidance for how production web services on this host should execute (for example: compiled JS or framework standalone output, not tsx/ts-node)."
|
|
101
|
+
},
|
|
102
|
+
"forbid_typescript_runtime": {
|
|
103
|
+
"type": "boolean",
|
|
104
|
+
"description": "Whether long-lived production web processes on this host should forbid tsx/ts-node style runtime transpilation."
|
|
105
|
+
},
|
|
106
|
+
"prefer_standalone_output": {
|
|
107
|
+
"type": "boolean",
|
|
108
|
+
"description": "Whether frameworks that support a minimal standalone runtime (for example Next.js standalone output) should prefer it on this host."
|
|
109
|
+
},
|
|
110
|
+
"scheduler_placement": {
|
|
111
|
+
"type": "string",
|
|
112
|
+
"minLength": 1,
|
|
113
|
+
"description": "Operator-facing guidance for where scheduled/background jobs should run on this host."
|
|
114
|
+
}
|
|
115
|
+
},
|
|
116
|
+
"description": "Host-level runtime-efficiency contract. Not consumed by templates yet, but validated so the lean-production guidance stays explicit and versioned."
|
|
117
|
+
},
|
|
87
118
|
"notes": {
|
|
88
119
|
"type": "array",
|
|
89
120
|
"items": { "type": "string", "minLength": 1 },
|
|
@@ -24,9 +24,16 @@
|
|
|
24
24
|
"runner": "ubuntu-latest"
|
|
25
25
|
}
|
|
26
26
|
},
|
|
27
|
+
"runtime_contract": {
|
|
28
|
+
"preferred_web_runtime": "compiled JavaScript or framework standalone output",
|
|
29
|
+
"forbid_typescript_runtime": true,
|
|
30
|
+
"prefer_standalone_output": true,
|
|
31
|
+
"scheduler_placement": "scheduled and background jobs should run in a separate worker, cron, or function rather than inside the long-lived web process"
|
|
32
|
+
},
|
|
27
33
|
"notes": [
|
|
28
34
|
"Railway auto-deploys on push to main; no explicit deploy step needed in CI.",
|
|
29
35
|
"Production URL is set as a repo secret (name configured per-project via production_url_secret in sdlc-config.json).",
|
|
30
|
-
"Test-time database services are declared per-project (database_service, database_image, database_port, database_env) so CI can spin up a matching container alongside the app container."
|
|
36
|
+
"Test-time database services are declared per-project (database_service, database_image, database_port, database_env) so CI can spin up a matching container alongside the app container.",
|
|
37
|
+
"For long-lived production web services on Railway, do not run tsx/ts-node in production; use compiled JS or a framework's standalone runtime output."
|
|
31
38
|
]
|
|
32
39
|
}
|
|
@@ -38,6 +38,9 @@ echo "Pre-push: TypeScript check passed."
|
|
|
38
38
|
# Previous code had two `while read` loops; the second consumed nothing
|
|
39
39
|
# because stdin was already exhausted by the first (devaudit-installer#278).
|
|
40
40
|
PUSH_REFS="$(cat)"
|
|
41
|
+
PUSH_REFS_FILE=$(mktemp)
|
|
42
|
+
trap 'rm -f "$PUSH_REFS_FILE"' EXIT HUP INT TERM
|
|
43
|
+
printf '%s\n' "$PUSH_REFS" > "$PUSH_REFS_FILE"
|
|
41
44
|
|
|
42
45
|
INTEGRATION_BRANCH=$(jq -r '.integration_branch // "develop"' sdlc-config.json 2>/dev/null || echo "develop")
|
|
43
46
|
|
|
@@ -49,7 +52,8 @@ INTEGRATION_BRANCH=$(jq -r '.integration_branch // "develop"' sdlc-config.json 2
|
|
|
49
52
|
# (written by e2e-test-engineer Phase 5½ after validating tagTest/evidenceShot).
|
|
50
53
|
# Scoped to integration-branch pushes (correct for the normal workflow).
|
|
51
54
|
|
|
52
|
-
|
|
55
|
+
while read -r local_ref local_sha remote_ref remote_sha; do
|
|
56
|
+
[ -n "${local_ref:-}" ] || continue
|
|
53
57
|
# Check if pushing to the integration branch
|
|
54
58
|
case "$remote_ref" in
|
|
55
59
|
*"refs/heads/$INTEGRATION_BRANCH") ;;
|
|
@@ -103,7 +107,7 @@ echo "$PUSH_REFS" | while read -r local_ref local_sha remote_ref remote_sha; do
|
|
|
103
107
|
fi
|
|
104
108
|
echo "Pre-push: E2E evidence wiring check passed."
|
|
105
109
|
fi
|
|
106
|
-
done
|
|
110
|
+
done < "$PUSH_REFS_FILE"
|
|
107
111
|
|
|
108
112
|
# ── 3. Skill-invocation sentinel (devaudit-installer#226) ────────────
|
|
109
113
|
# If feat/fix/refactor/perf commits are in the push, verify the
|
|
@@ -115,11 +119,9 @@ done
|
|
|
115
119
|
TRACKED_TYPES='^(feat|fix|refactor|perf)(\(.+\))?!?:'
|
|
116
120
|
HAS_TRACKED=false
|
|
117
121
|
|
|
118
|
-
# Parse
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
local_sha="$2"
|
|
122
|
-
remote_sha="$4"
|
|
122
|
+
# Parse captured refs in the current shell so HAS_TRACKED propagates.
|
|
123
|
+
while read -r local_ref local_sha remote_ref remote_sha; do
|
|
124
|
+
[ -n "${local_ref:-}" ] || continue
|
|
123
125
|
if [ "$remote_sha" = "0000000000000000000000000000000000000000" ]; then
|
|
124
126
|
RANGE="$local_sha"
|
|
125
127
|
else
|
|
@@ -129,7 +131,7 @@ for ref_line in $PUSH_REFS; do
|
|
|
129
131
|
if echo "$COMMITS" | grep -qE "$TRACKED_TYPES"; then
|
|
130
132
|
HAS_TRACKED=true
|
|
131
133
|
fi
|
|
132
|
-
done
|
|
134
|
+
done < "$PUSH_REFS_FILE"
|
|
133
135
|
|
|
134
136
|
if [ "$HAS_TRACKED" = "true" ]; then
|
|
135
137
|
if [ ! -f .sdlc-implementer-invoked ]; then
|
|
@@ -147,10 +149,8 @@ if [ "$HAS_TRACKED" = "true" ]; then
|
|
|
147
149
|
# If the commit touches Phase 3 artifacts (compliance/evidence/REQ-XXX/),
|
|
148
150
|
# the sentinel must contain a phase "3" record. If it touches Phase 5
|
|
149
151
|
# close-out (approved-releases/ or RTM RELEASED), sentinel must have phase "5".
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
local_sha="$2"
|
|
153
|
-
remote_sha="$4"
|
|
152
|
+
while read -r local_ref local_sha remote_ref remote_sha; do
|
|
153
|
+
[ -n "${local_ref:-}" ] || continue
|
|
154
154
|
if [ "$remote_sha" = "0000000000000000000000000000000000000000" ]; then
|
|
155
155
|
RANGE="$local_sha"
|
|
156
156
|
else
|
|
@@ -181,7 +181,7 @@ if [ "$HAS_TRACKED" = "true" ]; then
|
|
|
181
181
|
exit 1
|
|
182
182
|
fi
|
|
183
183
|
fi
|
|
184
|
-
done
|
|
184
|
+
done < "$PUSH_REFS_FILE"
|
|
185
185
|
echo "Pre-push: phase-progression check passed."
|
|
186
186
|
fi
|
|
187
187
|
|
package/sdlc/package.json
CHANGED