@metasession.co/devaudit-cli 0.1.29 → 0.1.31
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 +92 -35
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/sdlc/files/_common/governance/ai-disclosure.md.template +91 -0
- package/sdlc/files/_common/governance/dpia.md.template +78 -0
- package/sdlc/files/_common/governance/incident-report.md.template +111 -0
- package/sdlc/files/_common/governance/periodic-review.md.template +109 -0
- package/sdlc/files/_common/governance/ropa.md.template +59 -0
- package/sdlc/files/ci/incident-export.yml.template +173 -0
- package/sdlc/files/ci/periodic-review.yml.template +218 -0
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
# Periodic Review — quarterly auto-generation of compliance/governance/periodic-review.md
|
|
2
|
+
#
|
|
3
|
+
# Generated by `devaudit install` / `devaudit update` from sdlc-config.json.
|
|
4
|
+
# Do not edit manually — re-run the CLI (`devaudit update`) to regenerate.
|
|
5
|
+
#
|
|
6
|
+
# Why this exists:
|
|
7
|
+
# - SOC 2 CC4.1 (Monitoring of internal controls) and ISO 27001 A.12.1
|
|
8
|
+
# (Operational procedures and responsibilities) require periodic
|
|
9
|
+
# review of controls + procedures. The portal flags `periodic_review`
|
|
10
|
+
# evidence as `expired` after 365 days.
|
|
11
|
+
# - The v0.1.30 starter at compliance/governance/periodic-review.md
|
|
12
|
+
# covers the operator's first attestation. This workflow auto-
|
|
13
|
+
# regenerates it quarterly with locally-derived metrics + a clearly-
|
|
14
|
+
# marked "Review notes (operator fills in)" section, opens a PR so
|
|
15
|
+
# a human reviews + approves before it lands on develop, then
|
|
16
|
+
# compliance-evidence.yml uploads it as `periodic_review` evidence.
|
|
17
|
+
#
|
|
18
|
+
# DevAudit-Installer#98 WS3.
|
|
19
|
+
|
|
20
|
+
name: Periodic Review
|
|
21
|
+
|
|
22
|
+
on:
|
|
23
|
+
schedule:
|
|
24
|
+
# Quarterly: 1st of Jan / Apr / Jul / Oct at 09:00 UTC.
|
|
25
|
+
- cron: '0 9 1 */3 *'
|
|
26
|
+
workflow_dispatch:
|
|
27
|
+
|
|
28
|
+
permissions:
|
|
29
|
+
contents: write
|
|
30
|
+
pull-requests: write
|
|
31
|
+
|
|
32
|
+
jobs:
|
|
33
|
+
generate:
|
|
34
|
+
name: Generate quarterly periodic-review.md
|
|
35
|
+
runs-on: ubuntu-latest
|
|
36
|
+
steps:
|
|
37
|
+
- uses: actions/checkout@v4
|
|
38
|
+
with:
|
|
39
|
+
fetch-depth: 0
|
|
40
|
+
# Need write access for the chore branch.
|
|
41
|
+
token: ${{ secrets.DEVAUDIT_USER_TOKEN || github.token }}
|
|
42
|
+
|
|
43
|
+
- name: Compute review period
|
|
44
|
+
id: period
|
|
45
|
+
run: |
|
|
46
|
+
# End of period = today. Start = ~90 days back (rough quarter).
|
|
47
|
+
PERIOD_END=$(date -u +%Y-%m-%d)
|
|
48
|
+
PERIOD_START=$(date -u -d '90 days ago' +%Y-%m-%d)
|
|
49
|
+
REVIEW_ID=$(date -u +%Y-Q%q 2>/dev/null || date -u +%Y-%m)
|
|
50
|
+
BRANCH="chore/periodic-review-${REVIEW_ID//[^A-Za-z0-9-]/-}"
|
|
51
|
+
echo "period_start=${PERIOD_START}" >> "$GITHUB_OUTPUT"
|
|
52
|
+
echo "period_end=${PERIOD_END}" >> "$GITHUB_OUTPUT"
|
|
53
|
+
echo "review_id=${REVIEW_ID}" >> "$GITHUB_OUTPUT"
|
|
54
|
+
echo "branch=${BRANCH}" >> "$GITHUB_OUTPUT"
|
|
55
|
+
|
|
56
|
+
- name: Derive metrics from repo state
|
|
57
|
+
id: metrics
|
|
58
|
+
env:
|
|
59
|
+
GH_TOKEN: ${{ github.token }}
|
|
60
|
+
PERIOD_START: ${{ steps.period.outputs.period_start }}
|
|
61
|
+
run: |
|
|
62
|
+
# Counts come from local state — no portal API call needed.
|
|
63
|
+
# The portal can render against its own data; this summary is
|
|
64
|
+
# for the operator's review-and-attest moment.
|
|
65
|
+
RTM_REQS=0
|
|
66
|
+
PENDING_RELEASES=0
|
|
67
|
+
APPROVED_RELEASES=0
|
|
68
|
+
INCIDENT_REPORTS=0
|
|
69
|
+
if [ -f compliance/RTM.md ]; then
|
|
70
|
+
RTM_REQS=$(grep -oE '^\| REQ-[0-9]+ ' compliance/RTM.md | wc -l | tr -d ' ')
|
|
71
|
+
fi
|
|
72
|
+
if [ -d compliance/pending-releases ]; then
|
|
73
|
+
PENDING_RELEASES=$(find compliance/pending-releases -maxdepth 1 -name 'RELEASE-TICKET-REQ-*.md' -type f 2>/dev/null | wc -l | tr -d ' ')
|
|
74
|
+
fi
|
|
75
|
+
if [ -d compliance/approved-releases ]; then
|
|
76
|
+
APPROVED_RELEASES=$(find compliance/approved-releases -maxdepth 1 -name 'RELEASE-TICKET-REQ-*.md' -type f 2>/dev/null | wc -l | tr -d ' ')
|
|
77
|
+
fi
|
|
78
|
+
if [ -d compliance/governance ]; then
|
|
79
|
+
INCIDENT_REPORTS=$(find compliance/governance -maxdepth 1 -name 'incident-report*.md' -type f 2>/dev/null | wc -l | tr -d ' ')
|
|
80
|
+
fi
|
|
81
|
+
# CI pass-rate over the period — best-effort via gh.
|
|
82
|
+
CI_RUNS=$(gh run list --branch develop --limit 100 --json conclusion,createdAt 2>/dev/null || echo '[]')
|
|
83
|
+
TOTAL_RUNS=$(echo "$CI_RUNS" | jq --arg since "${PERIOD_START}T00:00:00Z" '[.[] | select(.createdAt >= $since)] | length' 2>/dev/null || echo 0)
|
|
84
|
+
PASSED_RUNS=$(echo "$CI_RUNS" | jq --arg since "${PERIOD_START}T00:00:00Z" '[.[] | select(.createdAt >= $since and .conclusion == "success")] | length' 2>/dev/null || echo 0)
|
|
85
|
+
PASS_RATE="n/a"
|
|
86
|
+
if [ "$TOTAL_RUNS" -gt 0 ]; then
|
|
87
|
+
PASS_RATE="$((100 * PASSED_RUNS / TOTAL_RUNS))%"
|
|
88
|
+
fi
|
|
89
|
+
{
|
|
90
|
+
echo "rtm_reqs=${RTM_REQS}"
|
|
91
|
+
echo "pending_releases=${PENDING_RELEASES}"
|
|
92
|
+
echo "approved_releases=${APPROVED_RELEASES}"
|
|
93
|
+
echo "incident_reports=${INCIDENT_REPORTS}"
|
|
94
|
+
echo "ci_total=${TOTAL_RUNS}"
|
|
95
|
+
echo "ci_passed=${PASSED_RUNS}"
|
|
96
|
+
echo "ci_pass_rate=${PASS_RATE}"
|
|
97
|
+
} >> "$GITHUB_OUTPUT"
|
|
98
|
+
|
|
99
|
+
- name: Render periodic-review.md
|
|
100
|
+
env:
|
|
101
|
+
PERIOD_START: ${{ steps.period.outputs.period_start }}
|
|
102
|
+
PERIOD_END: ${{ steps.period.outputs.period_end }}
|
|
103
|
+
REVIEW_ID: ${{ steps.period.outputs.review_id }}
|
|
104
|
+
RTM_REQS: ${{ steps.metrics.outputs.rtm_reqs }}
|
|
105
|
+
PENDING_RELEASES: ${{ steps.metrics.outputs.pending_releases }}
|
|
106
|
+
APPROVED_RELEASES: ${{ steps.metrics.outputs.approved_releases }}
|
|
107
|
+
INCIDENT_REPORTS: ${{ steps.metrics.outputs.incident_reports }}
|
|
108
|
+
CI_TOTAL: ${{ steps.metrics.outputs.ci_total }}
|
|
109
|
+
CI_PASSED: ${{ steps.metrics.outputs.ci_passed }}
|
|
110
|
+
CI_PASS_RATE: ${{ steps.metrics.outputs.ci_pass_rate }}
|
|
111
|
+
run: |
|
|
112
|
+
mkdir -p compliance/governance
|
|
113
|
+
cat > compliance/governance/periodic-review.md <<EOF
|
|
114
|
+
---
|
|
115
|
+
title: "Periodic Review of Internal Controls (${REVIEW_ID})"
|
|
116
|
+
period_start: "${PERIOD_START}"
|
|
117
|
+
period_end: "${PERIOD_END}"
|
|
118
|
+
reviewer: "REPLACE — name + role"
|
|
119
|
+
last_reviewed_at: "${PERIOD_END}"
|
|
120
|
+
review_cadence_days: 90
|
|
121
|
+
---
|
|
122
|
+
|
|
123
|
+
> ℹ️ Auto-generated by Periodic Review workflow on ${PERIOD_END}.
|
|
124
|
+
> The CI-derived metrics below are filled in automatically. The
|
|
125
|
+
> **Review notes** and **Sign-off** sections still require the
|
|
126
|
+
> human attestation — replace the REPLACE markers before merging
|
|
127
|
+
> this PR. Auditors will reject auto-generated stubs with no
|
|
128
|
+
> human attestation.
|
|
129
|
+
|
|
130
|
+
# Periodic Review of Internal Controls
|
|
131
|
+
|
|
132
|
+
**Framework coverage:** \`SOC2.CC4.1\` (Monitoring of internal controls), \`ISO27001.A.12.1\` (Operational procedures and responsibilities)
|
|
133
|
+
|
|
134
|
+
**Evidence type:** \`periodic_review\` · **Cadence:** every 90 days. The portal flags this evidence as \`expired\` after 365 days.
|
|
135
|
+
|
|
136
|
+
## 1. Review period
|
|
137
|
+
|
|
138
|
+
- **From:** ${PERIOD_START}
|
|
139
|
+
- **To:** ${PERIOD_END}
|
|
140
|
+
- **Reviewer:** REPLACE — name + role
|
|
141
|
+
- **Approver (different person, dual-actor):** REPLACE
|
|
142
|
+
|
|
143
|
+
## 2. Activity summary (auto-derived from repo state)
|
|
144
|
+
|
|
145
|
+
| Metric | Value |
|
|
146
|
+
| ----------------------------------------- | ------------------------- |
|
|
147
|
+
| Total tracked REQs in RTM | ${RTM_REQS} |
|
|
148
|
+
| Pending releases at period end | ${PENDING_RELEASES} |
|
|
149
|
+
| Approved releases (cumulative) | ${APPROVED_RELEASES} |
|
|
150
|
+
| Incident reports on disk | ${INCIDENT_REPORTS} |
|
|
151
|
+
| CI runs on \`develop\` (this period) | ${CI_TOTAL} |
|
|
152
|
+
| CI runs passing | ${CI_PASSED} |
|
|
153
|
+
| CI pass rate | ${CI_PASS_RATE} |
|
|
154
|
+
|
|
155
|
+
## 3. Review notes (operator fills in)
|
|
156
|
+
|
|
157
|
+
REPLACE — qualitative observations about the period. What worked? What didn't? What follow-ups are required? Reference incident reports under \`compliance/governance/incident-report-*.md\` if any.
|
|
158
|
+
|
|
159
|
+
## 4. Control-effectiveness judgement
|
|
160
|
+
|
|
161
|
+
REPLACE — for each material control area, document evidence + reviewer judgement:
|
|
162
|
+
|
|
163
|
+
- **Access control (ISO 27001 A.5.15):** REPLACE — effective / partially / not
|
|
164
|
+
- **Change management (ISO 27001 A.8.32 / SOC 2 CC8.1):** REPLACE
|
|
165
|
+
- **Security testing (ISO 27001 A.8.29):** REPLACE
|
|
166
|
+
- **Logging and monitoring (ISO 27001 A.8.16 / EUAIA Art. 12):** REPLACE
|
|
167
|
+
- **Operational procedures (ISO 27001 A.12.1):** REPLACE
|
|
168
|
+
|
|
169
|
+
## 5. Follow-up actions
|
|
170
|
+
|
|
171
|
+
| # | Finding | Severity | Owner | Due | Issue |
|
|
172
|
+
| - | ------- | -------- | ----- | --- | ----- |
|
|
173
|
+
| 1 | REPLACE | REPLACE | REPLACE | REPLACE | REPLACE |
|
|
174
|
+
|
|
175
|
+
## 6. Sign-off
|
|
176
|
+
|
|
177
|
+
| Role | Name | Date |
|
|
178
|
+
| -------------------------- | ------- | ------- |
|
|
179
|
+
| Reviewer | REPLACE | REPLACE |
|
|
180
|
+
| Approver (dual-actor) | REPLACE | REPLACE |
|
|
181
|
+
| Decision | REPLACE — controls effective / partially effective / not effective |
|
|
182
|
+
|
|
183
|
+
---
|
|
184
|
+
|
|
185
|
+
_Source data: \`compliance/RTM.md\`, \`compliance/pending-releases/\`, \`compliance/approved-releases/\`, \`compliance/governance/incident-report-*.md\`, GitHub Actions runs on \`develop\` since ${PERIOD_START}._
|
|
186
|
+
EOF
|
|
187
|
+
echo "Generated compliance/governance/periodic-review.md"
|
|
188
|
+
|
|
189
|
+
- name: Open / update review PR
|
|
190
|
+
env:
|
|
191
|
+
GH_TOKEN: ${{ secrets.DEVAUDIT_USER_TOKEN || github.token }}
|
|
192
|
+
BRANCH: ${{ steps.period.outputs.branch }}
|
|
193
|
+
REVIEW_ID: ${{ steps.period.outputs.review_id }}
|
|
194
|
+
run: |
|
|
195
|
+
# Configure git for the bot commit.
|
|
196
|
+
git config user.name 'devaudit-bot'
|
|
197
|
+
git config user.email 'devaudit-bot@users.noreply.github.com'
|
|
198
|
+
# Branch from develop. If a branch from a prior failed run exists,
|
|
199
|
+
# blow it away and start fresh; we always regenerate from the latest
|
|
200
|
+
# repo state.
|
|
201
|
+
git fetch origin develop
|
|
202
|
+
git checkout -B "${BRANCH}" origin/develop
|
|
203
|
+
git add compliance/governance/periodic-review.md
|
|
204
|
+
if git diff --cached --quiet; then
|
|
205
|
+
echo "No change to periodic-review.md — nothing to do."
|
|
206
|
+
exit 0
|
|
207
|
+
fi
|
|
208
|
+
git commit -m "chore(compliance): periodic review ${REVIEW_ID} (auto-generated)" -m "Quarterly periodic-review.md regenerated by Periodic Review workflow." -m "" -m "REPLACE markers in the Review notes / Control-effectiveness / Sign-off sections require human attestation before this PR can merge."
|
|
209
|
+
git push --force-with-lease origin "${BRANCH}"
|
|
210
|
+
# Open PR (or update existing).
|
|
211
|
+
EXISTING=$(gh pr list --head "${BRANCH}" --json number --jq '.[0].number' || true)
|
|
212
|
+
if [ -z "$EXISTING" ]; then
|
|
213
|
+
gh pr create --base develop --head "${BRANCH}" \
|
|
214
|
+
--title "chore(compliance): periodic review ${REVIEW_ID}" \
|
|
215
|
+
--body "Auto-generated quarterly periodic-review for **${REVIEW_ID}** by the \`Periodic Review\` workflow.\n\n**Required before merge:**\n- [ ] Replace \`REPLACE — …\` markers in the **Review notes** section\n- [ ] Fill in control-effectiveness judgement for each control area\n- [ ] Add reviewer + approver names (dual-actor)\n- [ ] List follow-up actions with owners + dates\n\nSee [\`docs/governance-templates.md\`](https://github.com/metasession-dev/DevAudit-Installer/blob/main/docs/governance-templates.md#soc-2--trust-services-criteria) (SDLC repo) for guidance.\n\nCloses \`SOC2.CC4.1\` + \`ISO27001.A.12.1\` for the period once the PR lands on develop."
|
|
216
|
+
else
|
|
217
|
+
echo "PR #${EXISTING} already open for this period — branch updated in place."
|
|
218
|
+
fi
|