@metasession.co/devaudit-cli 0.1.28 → 0.1.30

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@metasession.co/devaudit-cli",
3
- "version": "0.1.28",
3
+ "version": "0.1.30",
4
4
  "description": "DevAudit CLI — installs, syncs, and operates the Metasession SDLC across consumer projects.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -33,7 +33,7 @@
33
33
  },
34
34
  "dependencies": {
35
35
  "@clack/prompts": "^0.8.2",
36
- "@metasession.co/devaudit-plugin-sdk": "^0.1.28",
36
+ "@metasession.co/devaudit-plugin-sdk": "^0.1.30",
37
37
  "commander": "^12.1.0",
38
38
  "consola": "^3.2.3",
39
39
  "env-paths": "^3.0.0",
@@ -26,6 +26,12 @@
26
26
  # build / test / compliance / revert) for
27
27
  # the release row. Unknown values are
28
28
  # silently dropped server-side.
29
+ # --gate-status <status> `passed` / `failed` / `skipped`. Lets the
30
+ # portal distinguish a gate that ran-and-
31
+ # failed from one that never ran. Forwarded
32
+ # as `gateStatus`; unknown values are
33
+ # silently dropped server-side.
34
+ # DevAudit-Installer#96.
29
35
  #
30
36
  # Required environment variables:
31
37
  # DEVAUDIT_BASE_URL e.g. https://meta-comply-production.up.railway.app
@@ -65,6 +71,7 @@ ENVIRONMENT=""
65
71
  EVIDENCE_CATEGORY=""
66
72
  RELEASE_TITLE=""
67
73
  CHANGE_TYPE=""
74
+ GATE_STATUS=""
68
75
 
69
76
  while [ "$#" -gt 0 ]; do
70
77
  case "$1" in
@@ -80,6 +87,10 @@ while [ "$#" -gt 0 ]; do
80
87
  # unknown change-type values are dropped server-side, not 400'd.
81
88
  --release-title) RELEASE_TITLE="$2"; shift 2 ;;
82
89
  --change-type) CHANGE_TYPE="$2"; shift 2 ;;
90
+ # passed/failed/skipped — surfaces failed gates on the portal so
91
+ # ran-and-failed != never-ran. Unknown values dropped server-side.
92
+ # DevAudit-Installer#96.
93
+ --gate-status) GATE_STATUS="$2"; shift 2 ;;
83
94
  *) echo "Unknown option: $1"; exit 1 ;;
84
95
  esac
85
96
  done
@@ -181,6 +192,7 @@ for FILE in "${FILES[@]}"; do
181
192
  [ -n "$EVIDENCE_CATEGORY" ] && CURL_ARGS+=(-F "evidenceCategory=${EVIDENCE_CATEGORY}")
182
193
  [ -n "$RELEASE_TITLE" ] && CURL_ARGS+=(-F "releaseTitle=${RELEASE_TITLE}")
183
194
  [ -n "$CHANGE_TYPE" ] && CURL_ARGS+=(-F "changeType=${CHANGE_TYPE}")
195
+ [ -n "$GATE_STATUS" ] && CURL_ARGS+=(-F "gateStatus=${GATE_STATUS}")
184
196
 
185
197
  ATTEMPT=1
186
198
  BACKOFF=$INITIAL_BACKOFF_SECONDS
@@ -0,0 +1,91 @@
1
+ ---
2
+ title: "AI Use Disclosure (deployer-facing)"
3
+ provider: "REPLACE — legal name of the AI system provider"
4
+ intended_purpose: "REPLACE — one-line description of intended use"
5
+ last_reviewed_at: "REPLACE — YYYY-MM-DD"
6
+ review_cadence_days: 180
7
+ risk_class: "REPLACE — minimal | limited | high | unacceptable"
8
+ ---
9
+
10
+ > ⚠️ **STARTER TEMPLATE — REPLACE BEFORE GOING TO PRODUCTION.**
11
+ > This file was auto-installed by `devaudit install` as a starting point.
12
+ > It does **not** describe your project's actual AI use. Edit and commit.
13
+ > Auditors will reject unedited stubs. See `docs/governance-templates.md` for guidance.
14
+
15
+ # AI Use Disclosure — Provision of information to deployers
16
+
17
+ **Framework coverage:** `EUAIA.Art-13` (Transparency and provision of information to deployers)
18
+
19
+ **Evidence type:** `ai_disclosure` · **Cadence:** refresh every 180 days, or whenever an AI tool / model / prompt-class is added or substantively changed.
20
+
21
+ > The EU AI Act requires providers to give deployers (the people who put the AI system into use in their professional activity) **clear, comprehensive, accurate and unambiguous** information about the system's capabilities, limitations, and intended use. This file is that disclosure for our project — both for AI we develop and for third-party AI we incorporate.
22
+
23
+ ## 1. Intended purpose
24
+
25
+ - **What the AI system does:** REPLACE
26
+ - **Intended use cases:** REPLACE
27
+ - **Foreseeable misuse / out-of-scope use cases:** REPLACE
28
+
29
+ ## 2. Risk classification
30
+
31
+ - **Annex III high-risk category match:** REPLACE — none / list applicable categories
32
+ - **Final risk class (per Title III):** REPLACE — minimal / limited / high / unacceptable
33
+ - **Reasoning:** REPLACE
34
+
35
+ ## 3. AI tools and models in use
36
+
37
+ Add one row per AI tool / model / API. Delete this template row before your first audit.
38
+
39
+ | Tool / model | Vendor | Use case | Inputs (data classes) | Outputs | Risk class | Provider docs |
40
+ |---|---|---|---|---|---|---|
41
+ | REPLACE — e.g. GPT-4o | OpenAI | Code suggestion in IDE | Source code, no PII | Code suggestions | Limited | https://… |
42
+ | REPLACE | | | | | | |
43
+
44
+ ## 4. Human oversight (Art. 14)
45
+
46
+ - **Where humans intervene in the AI loop:** REPLACE — e.g. "Every AI-suggested change goes through a four-eyes code review before merge"
47
+ - **Authority of the human reviewer:** REPLACE — can they reject / override / stop the system? Document the path
48
+ - **Cross-reference to four-eyes release approval:** all releases require an approved-by audit event in the portal (closes `EUAIA.Art-14`)
49
+
50
+ ## 5. Capabilities and limitations
51
+
52
+ - **Known limitations:** REPLACE — failure modes, training data cut-off, hallucination risk
53
+ - **Accuracy / robustness metrics:** REPLACE — link to test reports / benchmark results
54
+ - **Conditions under which performance degrades:** REPLACE
55
+
56
+ ## 6. Data, training, validation
57
+
58
+ - **Training data provenance (if we train):** REPLACE — sources, licensing, consent
59
+ - **Fine-tuning, RAG, prompt engineering used:** REPLACE
60
+ - **Data flowing to third-party AI providers:** REPLACE — list each provider + what's sent + DPA / SCC reference (cross-link to ROPA)
61
+
62
+ ## 7. Logging and traceability (Art. 12)
63
+
64
+ - **What we log:** REPLACE — prompts, completions, user/agent identity, timestamp
65
+ - **Where logs live:** REPLACE — link to portal `audit_log` evidence pipeline
66
+ - **Retention:** REPLACE
67
+ - **Closes `EUAIA.Art-12` via the `audit_log` snapshot uploaded each release.**
68
+
69
+ ## 8. Deployer obligations
70
+
71
+ - **What deployers must do to use the system safely:** REPLACE — link to operator runbook
72
+ - **Notification of substantial modifications:** REPLACE — process
73
+
74
+ ## 9. Sign-off
75
+
76
+ | Role | Name | Date |
77
+ |---|---|---|
78
+ | Provider responsible | REPLACE | REPLACE |
79
+ | AI compliance reviewer | REPLACE | REPLACE |
80
+
81
+ ## Sources
82
+
83
+ - [EU AI Act (Regulation 2024/1689)](https://eur-lex.europa.eu/eli/reg/2024/1689/oj) — especially Art. 9–15 (high-risk requirements) and Title IV (transparency)
84
+ - [NIST AI Risk Management Framework](https://www.nist.gov/itl/ai-risk-management-framework)
85
+ - [Anthropic Responsible Scaling Policy](https://www.anthropic.com/news/anthropics-responsible-scaling-policy) (example provider disclosure)
86
+
87
+ ## Review log
88
+
89
+ | Date | Reviewer | Changes |
90
+ |---|---|---|
91
+ | REPLACE — YYYY-MM-DD | REPLACE | Initial AI disclosure authored from starter template |
@@ -0,0 +1,78 @@
1
+ ---
2
+ title: "Data Protection Impact Assessment (DPIA)"
3
+ processing_activity: "REPLACE — short name of the activity assessed"
4
+ controller: "REPLACE — legal name of the controller"
5
+ last_reviewed_at: "REPLACE — YYYY-MM-DD"
6
+ review_cadence_days: 365
7
+ risk_level: "REPLACE — low | medium | high"
8
+ ---
9
+
10
+ > ⚠️ **STARTER TEMPLATE — REPLACE BEFORE GOING TO PRODUCTION.**
11
+ > This file was auto-installed by `devaudit install` as a starting point.
12
+ > It does **not** describe your project's actual data protection risks. Edit and commit.
13
+ > Auditors will reject unedited stubs. See `docs/governance-templates.md` for guidance.
14
+
15
+ # Data Protection Impact Assessment
16
+
17
+ **Framework coverage:** `GDPR.Art-35` (Data protection impact assessment)
18
+
19
+ **Evidence type:** `dpia` · **Cadence:** refresh every 365 days, or whenever the processing materially changes.
20
+
21
+ > A DPIA is **mandatory** for processing likely to result in high risk to data subjects: large-scale special-category data, systematic monitoring, automated decision-making with legal effect, etc. See Art. 35(3) and your supervisory authority's "blacklist" guidance.
22
+
23
+ ## 1. Description of the processing
24
+
25
+ - **Activity name:** REPLACE
26
+ - **Nature, scope, context, purposes:** REPLACE — what data is processed, how, why, for whom, at what scale
27
+ - **Data flow diagram or reference:** REPLACE — link to architecture doc / threat model
28
+ - **Cross-reference to ROPA:** `compliance/governance/ropa.md` activity REPLACE
29
+
30
+ ## 2. Necessity and proportionality
31
+
32
+ - **Lawful basis (Art. 6):** REPLACE
33
+ - **Special-category basis (Art. 9), if applicable:** REPLACE
34
+ - **Less-intrusive alternatives considered:** REPLACE
35
+ - **Data minimisation:** REPLACE — what's not collected and why
36
+ - **Retention justification:** REPLACE
37
+ - **Data subject rights — how exercised:** REPLACE — link to SAR procedure, rectification, erasure, portability
38
+
39
+ ## 3. Risks to rights and freedoms
40
+
41
+ For each risk, populate one row. Add or remove rows to fit your assessment.
42
+
43
+ | # | Risk | Likelihood (1–3) | Severity (1–3) | Inherent risk | Existing controls | Residual risk | Acceptable? |
44
+ |---|---|---|---|---|---|---|---|
45
+ | 1 | REPLACE — e.g. unauthorised access to user accounts | REPLACE | REPLACE | REPLACE | REPLACE — MFA, RBAC, encryption-at-rest | REPLACE | REPLACE Y/N |
46
+ | 2 | REPLACE | | | | | | |
47
+
48
+ ## 4. Measures to address the risks
49
+
50
+ - **Technical measures:** REPLACE — encryption, pseudonymisation, access controls, logging
51
+ - **Organisational measures:** REPLACE — training, policies, contractual safeguards
52
+ - **Residual high risk?** REPLACE — if YES, you must consult the supervisory authority (Art. 36) **before** processing begins. Document the consultation outcome.
53
+
54
+ ## 5. Consultation
55
+
56
+ - **DPO opinion:** REPLACE — name, date, conclusion
57
+ - **Data subjects / representatives consulted:** REPLACE — describe or document why not
58
+ - **Supervisory authority prior consultation:** REPLACE — required only when residual high risk remains
59
+
60
+ ## 6. Sign-off
61
+
62
+ | Role | Name | Date | Decision |
63
+ |---|---|---|---|
64
+ | Controller | REPLACE | REPLACE | REPLACE — approved / rejected / conditional |
65
+ | DPO | REPLACE | REPLACE | REPLACE |
66
+ | Technical lead | REPLACE | REPLACE | REPLACE |
67
+
68
+ ## Sources
69
+
70
+ - [EDPB DPIA guidelines (WP248 rev.01)](https://edpb.europa.eu/our-work-tools/our-documents/guidelines/)
71
+ - [ICO DPIA template](https://ico.org.uk/for-organisations/uk-gdpr-guidance-and-resources/accountability-and-governance/data-protection-impact-assessments-dpias/)
72
+ - [CNIL PIA software](https://www.cnil.fr/en/open-source-pia-software-helps-carry-out-data-protection-impact-assessment)
73
+
74
+ ## Review log
75
+
76
+ | Date | Reviewer | Changes |
77
+ |---|---|---|
78
+ | REPLACE — YYYY-MM-DD | REPLACE | Initial DPIA authored from starter template |
@@ -0,0 +1,111 @@
1
+ ---
2
+ title: "Incident Report"
3
+ incident_id: "REPLACE — e.g. INC-2026-001"
4
+ severity: "REPLACE — low | medium | high | critical"
5
+ detected_at: "REPLACE — ISO-8601 with timezone"
6
+ resolved_at: "REPLACE — ISO-8601 or 'ongoing'"
7
+ involves_personal_data: "REPLACE — true | false"
8
+ reported_to_supervisory_authority: "REPLACE — true | false | n/a"
9
+ notification_window_72h: "REPLACE — within | outside | n/a"
10
+ last_reviewed_at: "REPLACE — YYYY-MM-DD"
11
+ ---
12
+
13
+ > ⚠️ **STARTER TEMPLATE — REPLACE BEFORE GOING TO PRODUCTION.**
14
+ > This file was auto-installed by `devaudit install` as a starting point.
15
+ > If you reach for this file it's because something **happened** — replace this banner
16
+ > with the actual incident details. One incident per file (rename to
17
+ > `incident-report-<id>.md` if you keep multiple). Auditors will reject unedited stubs.
18
+
19
+ # Incident Report
20
+
21
+ **Framework coverage:**
22
+
23
+ - `ISO29119.3.5.4` (Test incident report)
24
+ - `SOC2.CC7.2` (System monitoring and incident response)
25
+ - `GDPR.Art-33` (Notification of a personal data breach to the supervisory authority — 72h)
26
+ - `GDPR.Art-34` (Communication of a personal data breach to the data subject)
27
+
28
+ **Evidence type:** `incident_report` · One artefact can satisfy multiple clauses depending on its scope (test defect, ops incident, personal-data breach).
29
+
30
+ ## 1. Summary
31
+
32
+ - **Incident ID:** REPLACE
33
+ - **Severity:** REPLACE — low / medium / high / critical
34
+ - **One-line description:** REPLACE
35
+ - **Detected at:** REPLACE — when was it first noticed
36
+ - **Resolved at:** REPLACE — or "ongoing"
37
+ - **Duration:** REPLACE
38
+
39
+ ## 2. Personal data scope (GDPR triage)
40
+
41
+ | Question | Answer |
42
+ |---|---|
43
+ | Did the incident involve personal data? | REPLACE — Y / N |
44
+ | If Y: estimated number of data subjects affected | REPLACE |
45
+ | If Y: categories of personal data involved | REPLACE |
46
+ | If Y: likely consequences for data subjects | REPLACE |
47
+ | **Notify supervisory authority (Art. 33)?** | REPLACE — required if Y and risk to rights/freedoms |
48
+ | **Notify data subjects (Art. 34)?** | REPLACE — required if high risk to rights/freedoms |
49
+ | 72-hour notification window: | REPLACE — within / outside / n/a; if outside, explain delay |
50
+
51
+ ## 3. Timeline
52
+
53
+ | Time (UTC) | Event |
54
+ |---|---|
55
+ | REPLACE — ISO-8601 | REPLACE — first signal observed |
56
+ | REPLACE | REPLACE — detection escalated to on-call |
57
+ | REPLACE | REPLACE — incident channel opened, IC assigned |
58
+ | REPLACE | REPLACE — mitigation deployed |
59
+ | REPLACE | REPLACE — incident declared resolved |
60
+ | REPLACE | REPLACE — supervisory authority notified (if applicable) |
61
+ | REPLACE | REPLACE — data subjects notified (if applicable) |
62
+
63
+ ## 4. Root cause
64
+
65
+ - **What happened:** REPLACE — technical narrative
66
+ - **Why it happened:** REPLACE — 5-whys or equivalent
67
+ - **Why it wasn't caught earlier:** REPLACE — gap in monitoring / testing / review
68
+
69
+ ## 5. Impact
70
+
71
+ - **Users affected:** REPLACE — count + segment
72
+ - **Data confidentiality / integrity / availability impact:** REPLACE
73
+ - **Financial / reputational:** REPLACE
74
+ - **Regulatory:** REPLACE
75
+
76
+ ## 6. Containment, mitigation, and recovery
77
+
78
+ - **Containment actions:** REPLACE
79
+ - **Mitigation deployed (link PRs):** REPLACE
80
+ - **Recovery actions:** REPLACE
81
+ - **Verification that the incident is resolved:** REPLACE
82
+
83
+ ## 7. Communications
84
+
85
+ - **Internal:** REPLACE — who was notified, when
86
+ - **Customer / data subjects:** REPLACE — channel, content (attach), timing
87
+ - **Supervisory authority:** REPLACE — body, reference number, content (attach)
88
+ - **Public statement:** REPLACE — link if any
89
+
90
+ ## 8. Lessons learned and follow-ups
91
+
92
+ - **What worked well:** REPLACE
93
+ - **What didn't:** REPLACE
94
+ - **Follow-up actions (issue links, owners, due dates):** REPLACE — file GitHub issues; one row per action
95
+ - [ ] REPLACE — owner @REPLACE — due REPLACE
96
+ - [ ] REPLACE — owner @REPLACE — due REPLACE
97
+
98
+ ## 9. Sign-off
99
+
100
+ | Role | Name | Date |
101
+ |---|---|---|
102
+ | Incident Commander | REPLACE | REPLACE |
103
+ | Engineering lead | REPLACE | REPLACE |
104
+ | DPO (if personal data involved) | REPLACE | REPLACE |
105
+ | Security lead | REPLACE | REPLACE |
106
+
107
+ ## Sources
108
+
109
+ - [ICO breach reporting guidance](https://ico.org.uk/for-organisations/report-a-breach/personal-data-breach/) (UK)
110
+ - [EDPB Guidelines 9/2022 on personal data breach notification](https://edpb.europa.eu/our-work-tools/our-documents/guidelines/)
111
+ - [SOC 2 Trust Services Criteria — CC7 (System Operations)](https://www.aicpa-cima.com/topic/audit-assurance/trust-services-criteria)
@@ -0,0 +1,107 @@
1
+ ---
2
+ title: "Periodic Review of Internal Controls"
3
+ period_start: "REPLACE — YYYY-MM-DD"
4
+ period_end: "REPLACE — YYYY-MM-DD"
5
+ reviewer: "REPLACE — name + role"
6
+ last_reviewed_at: "REPLACE — YYYY-MM-DD"
7
+ review_cadence_days: 90
8
+ ---
9
+
10
+ > ⚠️ **STARTER TEMPLATE — REPLACE BEFORE GOING TO PRODUCTION.**
11
+ > This file was auto-installed by `devaudit install` as a starting point.
12
+ > Once Workstream 3 ships (`.github/workflows/periodic-review.yml`), this file will be
13
+ > auto-regenerated quarterly with portal metrics. Until then — and to add the human
14
+ > attestation the auto-generator can't produce — edit this file yourself. Auditors
15
+ > will reject unedited stubs. See `docs/governance-templates.md` for guidance.
16
+
17
+ # Periodic Review of Internal Controls
18
+
19
+ **Framework coverage:**
20
+
21
+ - `SOC2.CC4.1` (Monitoring of internal controls)
22
+ - `ISO27001.A.12.1` (Operational procedures and responsibilities)
23
+
24
+ **Evidence type:** `periodic_review` · **Cadence:** every 90 days (quarterly). The portal flags this evidence as `expired` after 365 days — but a 90-day cadence is the practical minimum.
25
+
26
+ ## 1. Review period
27
+
28
+ - **From:** REPLACE — YYYY-MM-DD
29
+ - **To:** REPLACE — YYYY-MM-DD
30
+ - **Reviewer:** REPLACE — name + role
31
+ - **Approver (different person, if dual-actor required):** REPLACE
32
+
33
+ ## 2. Activity summary (CI-derived, auto-fill when WS3 lands)
34
+
35
+ | Metric | Value | Notes |
36
+ |---|---|---|
37
+ | Releases shipped this period | REPLACE | Tracked + housekeeping combined |
38
+ | Tracked releases (REQ-XXX) | REPLACE | |
39
+ | Quality-gate pass rate | REPLACE — % | % of CI runs where every gate passed |
40
+ | SAST findings net change | REPLACE | +/- vs. previous period |
41
+ | Dependency-audit unaccepted high/critical | REPLACE | Current count |
42
+ | Audit-log entries | REPLACE | Total in period |
43
+ | Open SDLC issues at period end | REPLACE | From `gh issue list --label requirement --state open` |
44
+
45
+ ## 3. Control-effectiveness review
46
+
47
+ For each control area, document evidence + reviewer judgement.
48
+
49
+ ### 3a. Access control (ISO 27001 A.5.15)
50
+
51
+ - **Active access grants reviewed:** REPLACE — list or attach export
52
+ - **Grants revoked this period:** REPLACE — count + reason
53
+ - **Anomalies:** REPLACE — or "none"
54
+ - **Effective?** REPLACE — Y / N (if N, follow-up action below)
55
+
56
+ ### 3b. Change management (ISO 27001 A.8.32 / SOC 2 CC8.1)
57
+
58
+ - **Releases approved via four-eyes flow:** REPLACE — N of M
59
+ - **Self-approval blocked on MEDIUM/HIGH risk?** REPLACE — confirm enforcement
60
+ - **Effective?** REPLACE
61
+
62
+ ### 3c. Security testing (ISO 27001 A.8.29)
63
+
64
+ - **SAST gate pass rate:** REPLACE
65
+ - **Dependency-audit gate pass rate:** REPLACE
66
+ - **E2E gate pass rate:** REPLACE
67
+ - **Effective?** REPLACE
68
+
69
+ ### 3d. Logging and monitoring (ISO 27001 A.8.16 / EUAIA Art. 12)
70
+
71
+ - **Audit-log entries reviewed:** REPLACE — sample size + method
72
+ - **Anomalies escalated:** REPLACE — count
73
+ - **Effective?** REPLACE
74
+
75
+ ### 3e. Operational procedures (ISO 27001 A.12.1)
76
+
77
+ - **Procedures reviewed this period:** REPLACE — list (link `Periodic_Security_Review_Schedule.md` items completed)
78
+ - **Stale / out-of-date docs:** REPLACE
79
+ - **Effective?** REPLACE
80
+
81
+ ## 4. Incidents this period
82
+
83
+ - **Total incidents:** REPLACE — link each `compliance/governance/incident-report-*.md`
84
+ - **Personal-data breaches:** REPLACE — count
85
+ - **Mean time to detection (MTTD):** REPLACE
86
+ - **Mean time to resolution (MTTR):** REPLACE
87
+
88
+ ## 5. Findings and follow-up actions
89
+
90
+ | # | Finding | Severity | Owner | Due | Issue link |
91
+ |---|---|---|---|---|---|
92
+ | 1 | REPLACE | REPLACE | REPLACE | REPLACE | REPLACE |
93
+ | 2 | REPLACE | | | | |
94
+
95
+ ## 6. Sign-off
96
+
97
+ | Role | Name | Date |
98
+ |---|---|---|
99
+ | Reviewer | REPLACE | REPLACE |
100
+ | Approver (dual-actor) | REPLACE | REPLACE |
101
+ | Decision | REPLACE — controls effective / partially effective / not effective |
102
+
103
+ ## Sources
104
+
105
+ - [SOC 2 Trust Services Criteria — CC4 (Monitoring)](https://www.aicpa-cima.com/topic/audit-assurance/trust-services-criteria)
106
+ - [ISO/IEC 27001:2022 Annex A.12 — Operational security](https://www.iso.org/standard/82875.html)
107
+ - Your project's `Periodic_Security_Review_Schedule.md`
@@ -0,0 +1,59 @@
1
+ ---
2
+ title: "Records of Processing Activities (ROPA)"
3
+ controller: "REPLACE — legal name of the controller"
4
+ controller_contact: "REPLACE — DPO email or controller contact"
5
+ last_reviewed_at: "REPLACE — YYYY-MM-DD"
6
+ review_cadence_days: 365
7
+ processing_activities: []
8
+ ---
9
+
10
+ > ⚠️ **STARTER TEMPLATE — REPLACE BEFORE GOING TO PRODUCTION.**
11
+ > This file was auto-installed by `devaudit install` as a starting point.
12
+ > It does **not** describe your project's actual processing activities. Edit and commit.
13
+ > Auditors will reject unedited stubs. See `docs/governance-templates.md` for guidance.
14
+
15
+ # Records of Processing Activities
16
+
17
+ **Framework coverage:** `GDPR.Art-30` (Records of processing activities)
18
+
19
+ **Evidence type:** `ropa` · **Cadence:** refresh every 365 days (portal flags as `expired` after)
20
+
21
+ ## Controller
22
+
23
+ - **Legal name:** REPLACE
24
+ - **Address:** REPLACE
25
+ - **Contact / DPO:** REPLACE
26
+ - **Joint controllers / representatives:** REPLACE (or "none")
27
+
28
+ ## Processing activities
29
+
30
+ For each distinct processing activity your project performs, add one section below. Delete this template row before your first audit.
31
+
32
+ ### Activity 1 — REPLACE (e.g. "User authentication and session management")
33
+
34
+ | Field | Value |
35
+ |---|---|
36
+ | **Purpose(s) of processing** | REPLACE — why you process this data; lawful basis (Art. 6) |
37
+ | **Categories of data subjects** | REPLACE — e.g. customers, employees, prospects |
38
+ | **Categories of personal data** | REPLACE — e.g. name, email, IP address, hashed password |
39
+ | **Special categories (Art. 9)** | REPLACE — none / specify (health, biometric, etc.) |
40
+ | **Recipients / categories of recipients** | REPLACE — internal teams + named processors |
41
+ | **Third-country transfers** | REPLACE — none / list countries + safeguard (SCCs, adequacy) |
42
+ | **Retention period** | REPLACE — e.g. "duration of customer relationship + 7 years" |
43
+ | **Technical and organisational security measures** | REPLACE — link to ISO 27001 controls / Test_Policy.md / encryption details |
44
+
45
+ ### Activity 2 — REPLACE
46
+
47
+ (repeat the table above)
48
+
49
+ ## Sources
50
+
51
+ - [ICO ROPA template (UK)](https://ico.org.uk/for-organisations/uk-gdpr-guidance-and-resources/accountability-and-governance/documentation/records-of-processing/)
52
+ - [EDPB Guidelines on Article 30](https://edpb.europa.eu/our-work-tools/our-documents/guidelines/)
53
+ - Your privacy policy + DPIA (`compliance/governance/dpia.md`) should describe the same activities.
54
+
55
+ ## Review log
56
+
57
+ | Date | Reviewer | Changes |
58
+ |---|---|---|
59
+ | REPLACE — YYYY-MM-DD | REPLACE | Initial ROPA authored from starter template |
@@ -13,6 +13,9 @@
13
13
  # 4. Pending release ticket on disk: exactly one
14
14
  # compliance/pending-releases/RELEASE-TICKET-REQ-XXX.md
15
15
  # -> REQ-XXX
16
+ # 4-bis. RTM.md IN PROGRESS row: exactly one tracked REQ marked
17
+ # IN PROGRESS in compliance/RTM.md
18
+ # -> REQ-XXX
16
19
  # 5. Fallback: bare date -> v2026.05.17
17
20
  #
18
21
  # Step 4 (DevAudit-Installer#92) handles `chore:` / `docs:` / `ci:`
@@ -23,6 +26,12 @@
23
26
  # bare date — when exactly one ticket is open, attribute to it.
24
27
  # Multiple open tickets stays ambiguous → bare-date fallback.
25
28
  #
29
+ # Step 4-bis (DevAudit-Installer#95) is the zero-ceremony equivalent:
30
+ # RTM.md is the file the operator already maintains as the source of
31
+ # truth for release state. When step 4 finds no ticket and exactly one
32
+ # RTM row is IN PROGRESS, attribute to it. RTM_PATH defaults to
33
+ # compliance/RTM.md and is overridable via env.
34
+ #
26
35
  # The id is taken from a bracketed [REQ-XXX] tag (subject or body) or the
27
36
  # `Ref:` line — NOT from unbracketed prose (e.g. "target close: REQ-002" must
28
37
  # not win over "Ref: REQ-001"). Step 3 exists because a "Merge pull request"
@@ -83,5 +92,32 @@ if [ -d compliance/pending-releases ]; then
83
92
  fi
84
93
  fi
85
94
 
95
+ # 4-bis. RTM.md IN PROGRESS row: when exactly one REQ row in
96
+ # compliance/RTM.md (or $RTM_PATH) is marked IN PROGRESS, attribute the
97
+ # in-flight release to it. Reads the file the operator already
98
+ # maintains so chore/docs/ci sync commits don't need a manually-dropped
99
+ # pending-tickets file. Same exactly-one guard as step 4 — zero or
100
+ # multiple IN PROGRESS rows → ambiguous, fall through.
101
+ # DevAudit-Installer#95.
102
+ RTM_PATH="${RTM_PATH:-compliance/RTM.md}"
103
+ if [ -f "$RTM_PATH" ]; then
104
+ # Match REQ rows whose status column starts with `IN PROGRESS`.
105
+ # `\|[[:space:]]+IN PROGRESS` requires a pipe followed by whitespace,
106
+ # so legend rows (`| \`IN PROGRESS\``) and prose mentions don't match.
107
+ # Variable padding between REQ-ID and Status (Issue/Risk/Evidence
108
+ # columns) is fine — only the leading REQ-XXX and the status-cell
109
+ # marker matter.
110
+ IN_PROGRESS_REQS=$(grep -E '\|[[:space:]]+IN PROGRESS' "$RTM_PATH" 2>/dev/null \
111
+ | grep -oE '^\|[[:space:]]*REQ-[0-9]+' \
112
+ | grep -oE 'REQ-[0-9]+' | sort -u || true)
113
+ if [ -n "$IN_PROGRESS_REQS" ]; then
114
+ IN_PROGRESS_COUNT=$(echo "$IN_PROGRESS_REQS" | grep -c .)
115
+ if [ "$IN_PROGRESS_COUNT" = "1" ]; then
116
+ echo "$IN_PROGRESS_REQS"
117
+ exit 0
118
+ fi
119
+ fi
120
+ fi
121
+
86
122
  # 5. Fallback: bare date in UTC
87
123
  echo "v$(date -u +%Y.%m.%d)"
@@ -154,6 +154,89 @@ cat > compliance/pending-releases/RELEASE-TICKET-REQ-051.md <<'TICKET'
154
154
  TICKET
155
155
  assert_eq "subject [REQ-099] beats pending REQ-051 -> REQ-099" "REQ-099" "$(run_helper)"
156
156
 
157
+ # Case 13 (DevAudit-Installer#95): step-4-bis. No subject/body tag,
158
+ # no pending ticket, but RTM.md has exactly one IN PROGRESS row.
159
+ # Attribute to that REQ. Tests the zero-ceremony fallback that
160
+ # survives chore/docs/ci sync commits when no operator state file
161
+ # has been dropped.
162
+ make_fixture "$WORK/c13" "chore: devaudit update to 0.1.29"
163
+ mkdir -p compliance
164
+ cat > compliance/RTM.md <<'RTM'
165
+ # RTM
166
+ | REQ-ID | Issue | Risk | Evidence | Status | Approver | Date |
167
+ | ------- | ----- | ---- | ---------------------------- | ------------------- | -------- | ---------- |
168
+ | REQ-100 | #10 | LOW | compliance/evidence/REQ-100/ | APPROVED - DEPLOYED | dev | 2026-05-30 |
169
+ | REQ-101 | #11 | MED | compliance/evidence/REQ-101/ | IN PROGRESS | dev | 2026-06-01 |
170
+ RTM
171
+ assert_eq "RTM single IN PROGRESS row -> REQ-101" "REQ-101" "$(run_helper)"
172
+
173
+ # Case 14: step-4-bis ambiguity guard. Two IN PROGRESS rows → falls
174
+ # through to the bare date rather than guessing.
175
+ make_fixture "$WORK/c14" "chore: devaudit update to 0.1.29"
176
+ mkdir -p compliance
177
+ cat > compliance/RTM.md <<'RTM'
178
+ | REQ-ID | Status |
179
+ | ------- | -------------- |
180
+ | REQ-101 | IN PROGRESS |
181
+ | REQ-102 | IN PROGRESS |
182
+ RTM
183
+ assert_eq "RTM two IN PROGRESS rows -> bare date $TODAY" "$TODAY" "$(run_helper)"
184
+
185
+ # Case 15: step-4-bis must ignore legend rows that mention IN PROGRESS
186
+ # inside backticks (the wawagardenbar-app RTM convention) and prose
187
+ # mentions in description columns.
188
+ make_fixture "$WORK/c15" "chore: devaudit update to 0.1.29"
189
+ mkdir -p compliance
190
+ cat > compliance/RTM.md <<'RTM'
191
+ # RTM
192
+ ## Conventions
193
+ | Value | Meaning |
194
+ | ------------------ | ----------------------------- |
195
+ | `IN PROGRESS` | Active development underway |
196
+
197
+ | REQ-ID | Status |
198
+ | ------- | ----------------------------------------------------------------- |
199
+ | REQ-200 | RELEASED (was IN PROGRESS during Q3, then deployed) |
200
+ RTM
201
+ assert_eq "RTM legend + prose mentions -> bare date $TODAY" "$TODAY" "$(run_helper)"
202
+
203
+ # Case 16: step-4-bis with the real META-JOBS-shaped RTM row (long
204
+ # parenthetical commentary in the status cell). The status cell still
205
+ # starts with `IN PROGRESS` after the pipe.
206
+ make_fixture "$WORK/c16" "chore: devaudit update to 0.1.29"
207
+ mkdir -p compliance
208
+ cat > compliance/RTM.md <<'RTM'
209
+ | REQ-ID | Issue | Risk | Evidence | Status | Approver | Date |
210
+ | ------- | ----- | ----------- | ---------------------------- | --------------------------------------------------------------------- | ---------- | ---------- |
211
+ | REQ-056 | #117 | MEDIUM-HIGH | compliance/evidence/REQ-056/ | IN PROGRESS (WhatsApp inbound-message router; many details follow...) | ostendo-io | 2026-06-01 |
212
+ RTM
213
+ assert_eq "RTM long parenthetical status -> REQ-056" "REQ-056" "$(run_helper)"
214
+
215
+ # Case 17: step-4-bis must NOT win over a pending ticket on disk.
216
+ # Step 4 returns first.
217
+ make_fixture "$WORK/c17" "chore: devaudit update to 0.1.29"
218
+ mkdir -p compliance/pending-releases compliance
219
+ cat > compliance/pending-releases/RELEASE-TICKET-REQ-301.md <<'TICKET'
220
+ # Release Ticket: REQ-301
221
+ TICKET
222
+ cat > compliance/RTM.md <<'RTM'
223
+ | REQ-ID | Status |
224
+ | ------- | ----------- |
225
+ | REQ-302 | IN PROGRESS |
226
+ RTM
227
+ assert_eq "pending ticket REQ-301 beats RTM IN PROGRESS REQ-302" "REQ-301" "$(run_helper)"
228
+
229
+ # Case 18: step-4-bis respects RTM_PATH env override.
230
+ make_fixture "$WORK/c18" "chore: devaudit update to 0.1.29"
231
+ mkdir -p docs
232
+ cat > docs/custom-RTM.md <<'RTM'
233
+ | REQ-ID | Status |
234
+ | ------- | ----------- |
235
+ | REQ-400 | IN PROGRESS |
236
+ RTM
237
+ GOT=$(RTM_PATH=docs/custom-RTM.md run_helper)
238
+ assert_eq "RTM_PATH=docs/custom-RTM.md -> REQ-400" "REQ-400" "$GOT"
239
+
157
240
  echo ""
158
241
  echo "=== Summary: $PASS pass / $FAIL fail ==="
159
242
 
@@ -22,7 +22,10 @@ echo "Comparing: $BASE_BRANCH...HEAD"
22
22
  echo ""
23
23
 
24
24
  # Conventional Commit regex: type(optional-scope): description
25
- CC_REGEX='^(feat|fix|docs|test|refactor|chore|compliance|security|perf|ci|build|revert)(\([a-zA-Z0-9_-]+\))?!?: .+'
25
+ # Scope accepts anything except `)` so multi-scope subjects like
26
+ # `feat(auth,profile):` and `fix(rewards/expiry):` validate. The closing-paren
27
+ # guard prevents pathological inputs. DevAudit-Installer#93.
28
+ CC_REGEX='^(feat|fix|docs|test|refactor|chore|compliance|security|perf|ci|build|revert)(\([^)]+\))?!?: .+'
26
29
 
27
30
  COMMITS=$(git log "$BASE_BRANCH"..HEAD --format='%H' || true)
28
31