great-cto 2.12.1 → 2.15.0

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/adapt.js CHANGED
@@ -94,6 +94,7 @@ using it for pattern-matched work silently skips specialist review.
94
94
  | API contract: OpenAPI, GraphQL schema, webhook signatures | \`api-platform-reviewer\` |
95
95
  | Voice/IVR/telephony, Twilio, recording-consent, TCPA | \`voice-ai-reviewer\` |
96
96
  | Clinical / SaMD / FDA / FHIR / PHI | \`ai-clinical-reviewer\`, \`fda-reviewer\` |
97
+ | Wearable telemetry, HealthKit, Health Connect, Garmin, Samsung Health, fitness AI, mental health AI, nutrition AI, supplement AI, physician HITL | \`digital-health-reviewer\` |
97
98
  | Lending, ECOA, FCRA, NMLS, adverse action | \`lending-credit-reviewer\` |
98
99
  | HR-AI, hiring, AEDT, resume screening | \`hr-ai-reviewer\` |
99
100
  | Infra-as-code: Terraform / Helm / CDK / Pulumi | \`infra-reviewer\` |
package/dist/bootstrap.js CHANGED
@@ -3,6 +3,7 @@
3
3
  import { existsSync, mkdirSync, writeFileSync, readFileSync } from "node:fs";
4
4
  import { join } from "node:path";
5
5
  import { dim, success, warn } from "./ui.js";
6
+ import { suggestJurisdictions } from "./jurisdictions.js";
6
7
  export function bootstrap(dir, detection, archetype, compliance, detectionMeta) {
7
8
  const greatCtoDir = join(dir, ".great_cto");
8
9
  const projectMd = join(greatCtoDir, "PROJECT.md");
@@ -14,6 +15,10 @@ export function bootstrap(dir, detection, archetype, compliance, detectionMeta)
14
15
  const title = inferProjectTitle(dir);
15
16
  const stackLine = detection.stack.length > 0 ? detection.stack.join(", ") : "to be defined";
16
17
  const complianceLine = compliance.length > 0 ? compliance.join(", ") : "none";
18
+ const jurisdictionMatches = suggestJurisdictions(detection);
19
+ const jurisdictionLine = jurisdictionMatches.length > 0
20
+ ? jurisdictionMatches.map((m) => m.jurisdiction).join(", ")
21
+ : "unknown";
17
22
  const teamSize = 1; // MVP default — user edits later
18
23
  const approvalLevel = "gates-only"; // default per README
19
24
  const content = `# ${title}
@@ -55,9 +60,12 @@ approval-level: ${approvalLevel}
55
60
  ## Compliance
56
61
 
57
62
  compliance: [${complianceLine}]
63
+ jurisdiction: [${jurisdictionLine}]
58
64
 
59
65
  > \`compliance:\` list drives which checklists security-officer runs.
60
- > See ARCHETYPES.md "Parameter Values" for supported keys.
66
+ > \`jurisdiction:\` is auto-detected from README geo/legal signals — edit if wrong.
67
+ > Supported codes: eu · us · us-ca · uk · in · br · au · sg
68
+ > See docs/jurisdiction-compliance.md for what each code activates.
61
69
 
62
70
  ## Leash
63
71
 
package/dist/detect.js CHANGED
@@ -1163,6 +1163,55 @@ function mineReadmeKeywords(dir) {
1163
1163
  if (text.includes(term))
1164
1164
  kws.add(term);
1165
1165
  }
1166
+ // Jurisdiction geo/legal terms — emitted verbatim so jurisdictions.ts
1167
+ // can exact-match them. Keep in sync with JURISDICTION_SIGNALS in jurisdictions.ts.
1168
+ const jurisdictionTerms = [
1169
+ // EU
1170
+ "gdpr", "dsgvo", "rgpd", "data protection officer", "dpo",
1171
+ "right to erasure", "right to be forgotten", "data subject request",
1172
+ "article 6", "article 9", "legitimate interest", "lawful basis",
1173
+ "privacy by design", "privacy notice", "cookie consent",
1174
+ "eu ai act", "eu users", "eu customers", "european union",
1175
+ "eu data residency", "eu-west", "eu-central",
1176
+ "nis2", "dora ict risk", "dora compliance",
1177
+ "german users", "french users", "dutch users", "austrian",
1178
+ "italian users", "spanish users", "polish users",
1179
+ // US
1180
+ "ftc", "ftc act", "us users", "us customers", "united states",
1181
+ "american users", "coppa", "hipaa", "us privacy law",
1182
+ "virginia cdpa", "texas tdpsa", "florida fdbr",
1183
+ "colorado cpa", "connecticut ctdpa", "us state privacy",
1184
+ // US-CA
1185
+ "ccpa", "cpra", "california consumer privacy",
1186
+ "california privacy rights", "cppa", "california residents",
1187
+ "california users", "do not sell", "opt-out of sale",
1188
+ // UK
1189
+ "uk gdpr", "information commissioner", "dpa 2018",
1190
+ "uk users", "uk customers", "united kingdom", "british users",
1191
+ "fca consumer duty", "uk ai regulation",
1192
+ // IN
1193
+ "dpdpa", "digital personal data protection", "india data",
1194
+ "india users", "indian users", "bharat", "meity",
1195
+ "rbi data localisation", "rbi circular", "npci", "sebi",
1196
+ "india data residency",
1197
+ // BR
1198
+ "lgpd", "lei 13709", "anpd", "brazil users", "brazil customers",
1199
+ "brazilian users", "brasil", "data encarregado", "dpo brazil",
1200
+ "lgpd compliance",
1201
+ // AU
1202
+ "privacy act 1988", "australian privacy principles", "app principles",
1203
+ "oaic", "australia users", "australian users",
1204
+ "consumer data right", "notifiable data breach", "ndb scheme",
1205
+ "australia data residency",
1206
+ // SG
1207
+ "pdpa", "pdpc", "singapore users", "singaporean users",
1208
+ "mas guidelines", "mas tpm", "singpass", "myinfo",
1209
+ "singapore data residency",
1210
+ ];
1211
+ for (const term of jurisdictionTerms) {
1212
+ if (text.includes(term))
1213
+ kws.add(term);
1214
+ }
1166
1215
  return Array.from(kws).sort();
1167
1216
  }
1168
1217
  function safeGlob(dir, pattern, kind = "file") {
@@ -0,0 +1,156 @@
1
+ // Jurisdiction detection — auto-detect applicable compliance frameworks
2
+ // from project geography signals (README keywords, infra region hints).
3
+ //
4
+ // Three-axis detection model:
5
+ // archetype → what you build (ai-system, healthcare, fintech…)
6
+ // pack → what you use (digital-health-pack, lending-pack…)
7
+ // jurisdiction → where you operate (eu, us-ca, in, br, uk, au, sg)
8
+ //
9
+ // Jurisdiction overlays add specialist reviewer agents and human gates
10
+ // ON TOP OF archetype + pack pipelines.
11
+ // ── Compliance map ────────────────────────────────────────────────────────
12
+ const JURISDICTION_REVIEWERS = {
13
+ "eu": ["gdpr-reviewer"],
14
+ "us": ["us-privacy-reviewer"],
15
+ "us-ca": ["us-privacy-reviewer"],
16
+ "uk": ["gdpr-reviewer"], // UK GDPR closely mirrors EU GDPR
17
+ "in": ["dpdpa-reviewer"],
18
+ "br": ["gdpr-reviewer"], // LGPD mirrors GDPR — same reviewer covers
19
+ "au": ["us-privacy-reviewer"], // Privacy Act 1988 — covered by privacy reviewer
20
+ "sg": ["us-privacy-reviewer"], // PDPA — covered by privacy reviewer
21
+ };
22
+ const JURISDICTION_GATES = {
23
+ "eu": ["gate:gdpr-dpia", "gate:eu-ai-act-classification"],
24
+ "us": ["gate:us-state-privacy-matrix"],
25
+ "us-ca": ["gate:ccpa-dsrp", "gate:us-state-privacy-matrix"],
26
+ "uk": ["gate:uk-gdpr-dpia"],
27
+ "in": ["gate:dpdpa-consent-framework"],
28
+ "br": ["gate:lgpd-dpia"],
29
+ "au": ["gate:au-privacy-act-assessment"],
30
+ "sg": ["gate:pdpa-dpo"],
31
+ };
32
+ const JURISDICTION_LAWS = {
33
+ "eu": ["GDPR (EU) 2016/679", "EU AI Act 2024/1689", "NIS2 Directive 2022/2555", "ePrivacy Directive"],
34
+ "us": ["FTC Act § 5", "COPPA (if under-13)", "US state privacy laws (VA CDPA · TX TDPSA · FL FDBR · CO CPA · CT CTDPA)"],
35
+ "us-ca": ["CCPA / CPRA", "California AG enforcement", "CPPA rulemaking"],
36
+ "uk": ["UK GDPR", "DPA 2018", "ICO guidance", "FCA Consumer Duty (if fintech)"],
37
+ "in": ["DPDPA 2023 (Digital Personal Data Protection Act)", "IT Act 2000 § 43A", "SPDI Rules 2011", "RBI data localisation (if fintech)"],
38
+ "br": ["LGPD (Lei 13.709/2018)", "ANPD resolutions", "Marco Civil da Internet"],
39
+ "au": ["Privacy Act 1988 (Cth)", "Australian Privacy Principles (APPs)", "CDR (if fintech)", "OAIC enforcement"],
40
+ "sg": ["PDPA 2012 (amended 2021)", "MAS TRM Guidelines (if fintech)", "PDPC Advisory Guidelines"],
41
+ };
42
+ // ── Signal dictionary ─────────────────────────────────────────────────────
43
+ export const JURISDICTION_SIGNALS = {
44
+ "eu": {
45
+ keywords: [
46
+ // Legal / regulatory terms
47
+ "gdpr", "dsgvo", "rgpd", "data protection officer",
48
+ "right to erasure", "right to be forgotten", "data subject request",
49
+ "article 6", "article 9", "legitimate interest", "lawful basis",
50
+ "privacy by design", "privacy notice", "cookie consent",
51
+ "eu ai act", "eu users", "eu customers", "european union",
52
+ "eu data residency", "eu-west", "eu-central",
53
+ // NIS2 / DORA
54
+ "nis2", "dora ict risk", "dora compliance",
55
+ // Locales / markets
56
+ "german users", "french users", "dutch users", "austrian",
57
+ "italian users", "spanish users", "polish users",
58
+ ],
59
+ },
60
+ "us": {
61
+ keywords: [
62
+ "ftc", "ftc act", "us users", "us customers", "united states",
63
+ "american users", "coppa", "hipaa",
64
+ "virginia cdpa", "texas tdpsa", "florida fdbr", "colorado cpa",
65
+ "connecticut ctdpa", "us state privacy", "us privacy law",
66
+ ],
67
+ },
68
+ "us-ca": {
69
+ keywords: [
70
+ "ccpa", "cpra", "california consumer privacy",
71
+ "california privacy rights", "cppa", "california residents",
72
+ "california users", "do not sell", "opt-out of sale",
73
+ "data subject rights california", "dsr california",
74
+ ],
75
+ },
76
+ "uk": {
77
+ keywords: [
78
+ "uk gdpr", "information commissioner", "dpa 2018",
79
+ "uk users", "uk customers", "united kingdom", "british users",
80
+ "fca consumer duty", "uk ai regulation",
81
+ ],
82
+ },
83
+ "in": {
84
+ keywords: [
85
+ // Data protection
86
+ "dpdpa", "digital personal data protection", "india data",
87
+ "india users", "indian users", "bharat", "meity",
88
+ // Fintech / telecom
89
+ "rbi data localisation", "rbi circular", "npci", "sebi",
90
+ "india data residency",
91
+ ],
92
+ },
93
+ "br": {
94
+ keywords: [
95
+ "lgpd", "lei 13709", "anpd", "brazil users", "brazil customers",
96
+ "brazilian users", "brasil", "data encarregado", "dpo brazil",
97
+ "lgpd compliance",
98
+ ],
99
+ },
100
+ "au": {
101
+ keywords: [
102
+ "privacy act 1988", "australian privacy principles", "app principles",
103
+ "oaic", "australia users", "australian users",
104
+ "consumer data right", "notifiable data breach", "ndb scheme",
105
+ "australia data residency",
106
+ ],
107
+ },
108
+ "sg": {
109
+ keywords: [
110
+ "pdpa", "pdpc", "singapore users", "singaporean users",
111
+ "mas guidelines", "mas tpm", "singpass", "myinfo",
112
+ "singapore data residency",
113
+ ],
114
+ },
115
+ };
116
+ // ── Public API ─────────────────────────────────────────────────────────────
117
+ /** Return jurisdictions whose signals match the detection result. */
118
+ export function suggestJurisdictions(d) {
119
+ const matches = [];
120
+ const kwLower = d.readmeKeywords.map((k) => k.toLowerCase());
121
+ for (const code of Object.keys(JURISDICTION_SIGNALS)) {
122
+ const { keywords } = JURISDICTION_SIGNALS[code];
123
+ const matchedKeywords = keywords.filter((kw) => kwLower.includes(kw));
124
+ if (matchedKeywords.length === 0)
125
+ continue;
126
+ matches.push({
127
+ jurisdiction: code,
128
+ reviewers: JURISDICTION_REVIEWERS[code],
129
+ signals: matchedKeywords.slice(0, 8),
130
+ humanGates: JURISDICTION_GATES[code],
131
+ laws: JURISDICTION_LAWS[code],
132
+ });
133
+ }
134
+ matches.sort((a, b) => a.jurisdiction.localeCompare(b.jurisdiction));
135
+ return matches;
136
+ }
137
+ /** Flatten matched jurisdictions to unique sorted reviewer names. */
138
+ export function suggestJurisdictionReviewers(d) {
139
+ const all = new Set();
140
+ for (const m of suggestJurisdictions(d))
141
+ for (const r of m.reviewers)
142
+ all.add(r);
143
+ return Array.from(all).sort();
144
+ }
145
+ /** Flatten matched jurisdictions to unique sorted gate ids. */
146
+ export function suggestJurisdictionGates(d) {
147
+ const all = new Set();
148
+ for (const m of suggestJurisdictions(d))
149
+ for (const g of m.humanGates)
150
+ all.add(g);
151
+ return Array.from(all).sort();
152
+ }
153
+ /** Registry of all known jurisdiction codes — useful for /doctor. */
154
+ export function listJurisdictions() {
155
+ return Object.keys(JURISDICTION_SIGNALS).sort();
156
+ }
package/dist/packs.js CHANGED
@@ -1,6 +1,7 @@
1
1
  // Domain pack detection — overlay packs that ride on top of base archetypes.
2
2
  // Wave 1-3 (2026-05): voice, clinical, hr-ai, api-platform, lending, clinical-trials,
3
3
  // robotics, em-fintech, climate, drug-discovery.
4
+ // Wave 4 (2026-05): digital-health (wearable, mental-health, nutrition AI, physician HITL).
4
5
  //
5
6
  // A pack is a regulatory/domain overlay that triggers one or more specialist
6
7
  // reviewers (agents/{name}-reviewer.md) when its signals appear in stack,
@@ -19,6 +20,7 @@ const PACK_REVIEWERS = {
19
20
  "em-fintech-pack": ["emerging-markets-fintech-reviewer"],
20
21
  "climate-pack": ["climate-mrv-reviewer", "biosecurity-reviewer"],
21
22
  "drug-discovery-pack": ["drug-discovery-ml-reviewer", "glp-glab-reviewer", "lab-automation-reviewer"],
23
+ "digital-health-pack": ["digital-health-reviewer", "ai-clinical-reviewer", "healthcare-reviewer"],
22
24
  };
23
25
  const PACK_GATES = {
24
26
  "voice-pack": ["gate:voice-compliance"],
@@ -31,6 +33,7 @@ const PACK_GATES = {
31
33
  "em-fintech-pack": ["gate:license-strategy"],
32
34
  "climate-pack": ["gate:mrv-methodology", "gate:durc-signoff", "gate:open-weights-release"],
33
35
  "drug-discovery-pack": ["gate:model-card-signoff", "gate:csv-validation", "gate:iq-oq-pq"],
36
+ "digital-health-pack": ["gate:wellness-vs-samd", "gate:hitl-design", "gate:wearable-api-access", "gate:supplement-safety", "gate:mental-health-protocol"],
34
37
  };
35
38
  // Trigger signals — stack tokens OR README keywords.
36
39
  const SIGNALS = {
@@ -84,6 +87,25 @@ const SIGNALS = {
84
87
  "glp", "gmp", "gxp", "preclinical", "lims", "eln", "annex 11", "alcoa",
85
88
  "lab automation", "cloud lab", "robotic biology", "liquid handler", "hamilton", "tecan", "beckman", "opentrons", "plate reader", "sequencer", "hplc", "mass spec", "sila"],
86
89
  },
90
+ "digital-health-pack": {
91
+ stack: ["healthkit", "health-connect", "garmin-connect-iq", "samsung-health", "fitbit", "polar", "withings", "oura", "whoop"],
92
+ keywords: [
93
+ // wearable / biometric
94
+ "wearable", "apple watch", "apple health", "healthkit", "health connect", "garmin", "samsung health",
95
+ "google fit", "fitbit", "heart rate", "hrv", "heart rate variability", "spo2", "sleep tracking",
96
+ "sleep stages", "biometric sensor", "stress score", "activity tracking", "ecg wearable",
97
+ // mental health / wellness AI
98
+ "mental health", "mental wellness", "wellbeing", "mindfulness ai", "stress detection",
99
+ "burnout detection", "mood tracking", "anxiety ai", "depression ai", "phq-9", "gad-7",
100
+ "digital therapeutics", "dtx", "cbt app", "dbt app", "therapy ai",
101
+ // fitness / nutrition AI
102
+ "personalised training", "personalized training", "fitness ai", "nutrition ai",
103
+ "supplement recommendation", "supplement ai", "diet ai", "meal plan ai", "macro ai",
104
+ // HITL clinical
105
+ "physician review", "physician hitl", "doctor in the loop", "clinical review workflow",
106
+ "remote patient monitoring", "rpm", "teleconsultation",
107
+ ],
108
+ },
87
109
  };
88
110
  /** Return packs whose signals match the detection result. Deterministic + sorted. */
89
111
  export function suggestPacks(d) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "great-cto",
3
- "version": "2.12.1",
3
+ "version": "2.15.0",
4
4
  "description": "One command install for the great_cto Claude Code plugin. Auto-detects your stack, picks the right archetype, bootstraps PROJECT.md.",
5
5
  "keywords": [
6
6
  "claude-code",