fraim-framework 2.0.165 → 2.0.167
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/src/ai-hub/catalog.js +20 -27
- package/dist/src/ai-hub/server.js +418 -2
- package/dist/src/ai-hub/word-sideload.js +95 -0
- package/dist/src/cli/commands/org.js +40 -0
- package/dist/src/cli/commands/test-mcp.js +171 -0
- package/dist/src/cli/fraim.js +2 -0
- package/dist/src/cli/setup/first-run.js +242 -0
- package/dist/src/cli/utils/org-publish.js +98 -0
- package/dist/src/config/ai-manager-hiring.js +121 -0
- package/dist/src/config/compat.js +16 -0
- package/dist/src/config/feature-flags.js +25 -0
- package/dist/src/config/persona-capability-bundles.js +273 -0
- package/dist/src/config/persona-hiring.js +270 -0
- package/dist/src/config/portfolio-slug-overrides.js +17 -0
- package/dist/src/config/pricing.js +37 -0
- package/dist/src/config/stripe.js +43 -0
- package/dist/src/core/config-loader.js +9 -5
- package/dist/src/core/config-writer.js +75 -0
- package/dist/src/core/fraim-config-schema.generated.js +0 -21
- package/dist/src/core/utils/job-aliases.js +47 -0
- package/dist/src/core/utils/local-registry-resolver.js +8 -1
- package/dist/src/core/utils/workflow-parser.js +174 -0
- package/index.js +1 -1
- package/package.json +5 -1
- package/public/ai-hub/index.html +81 -0
- package/public/ai-hub/powerpoint-taskpane/index.html +236 -236
- package/public/ai-hub/powerpoint-taskpane/manifest.xml +29 -29
- package/public/ai-hub/review.css +13 -0
- package/public/ai-hub/script.js +414 -4
- package/public/ai-hub/styles.css +56 -0
- package/public/first-run/styles.css +73 -73
- package/public/portfolio/ashley.html +523 -0
- package/public/portfolio/auditya.html +83 -0
- package/public/portfolio/banke.html +83 -0
- package/public/portfolio/beza.html +659 -0
- package/public/portfolio/careena.html +632 -0
- package/public/portfolio/casey.html +568 -0
- package/public/portfolio/celia.html +490 -0
- package/public/portfolio/deidre.html +642 -0
- package/public/portfolio/gautam.html +597 -0
- package/public/portfolio/hari.html +469 -0
- package/public/portfolio/huxley.html +1354 -0
- package/public/portfolio/index.html +741 -0
- package/public/portfolio/maestro.html +518 -0
- package/public/portfolio/mandy.html +590 -0
- package/public/portfolio/mona.html +597 -0
- package/public/portfolio/pam.html +887 -0
- package/public/portfolio/procella.html +107 -0
- package/public/portfolio/qasm.html +569 -0
- package/public/portfolio/ricardo.html +489 -0
- package/public/portfolio/sade.html +560 -0
- package/public/portfolio/sam.html +654 -0
- package/public/portfolio/sechar.html +580 -0
- package/public/portfolio/sreya.html +599 -0
- package/public/portfolio/swen.html +601 -0
|
@@ -0,0 +1,599 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en" data-theme="light">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
+
<title>SREya · AI Site Reliability Engineer · FRAIM Portfolio</title>
|
|
7
|
+
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
8
|
+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
9
|
+
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&family=JetBrains+Mono:wght@400;600&display=swap" rel="stylesheet">
|
|
10
|
+
<style>
|
|
11
|
+
:root {
|
|
12
|
+
--accent: #2563eb;
|
|
13
|
+
--accent-2: #1d4ed8;
|
|
14
|
+
--accent-light: #dbeafe;
|
|
15
|
+
--text: #0c1a3a;
|
|
16
|
+
--text-2: #1e3a5f;
|
|
17
|
+
--muted: #1e40af;
|
|
18
|
+
--bg: #eff6ff;
|
|
19
|
+
--surface: #ffffff;
|
|
20
|
+
--surface-2: #eff6ff;
|
|
21
|
+
--border: #bfdbfe;
|
|
22
|
+
--shadow: 0 4px 24px rgba(37,99,235,.08);
|
|
23
|
+
--shadow-lg: 0 12px 40px rgba(37,99,235,.15);
|
|
24
|
+
--radius: 18px;
|
|
25
|
+
--radius-sm: 10px;
|
|
26
|
+
--green: #10b981;
|
|
27
|
+
--purple: #8b5cf6;
|
|
28
|
+
--amber: #f59e0b;
|
|
29
|
+
--red: #ef4444;
|
|
30
|
+
--code-bg: #0c1a3a;
|
|
31
|
+
--code-border: #1e3a5f;
|
|
32
|
+
}
|
|
33
|
+
[data-theme="dark"] {
|
|
34
|
+
--text: #bfdbfe; --text-2: #93c5fd; --muted: #7aafea;
|
|
35
|
+
--bg: #0c1a3a; --surface: #1e3a5f; --surface-2: #1e3463;
|
|
36
|
+
--border: #1d4ed8; --shadow: 0 4px 24px rgba(0,0,0,.35);
|
|
37
|
+
--shadow-lg: 0 12px 40px rgba(0,0,0,.5); --accent-light: #1d4ed8;
|
|
38
|
+
--code-bg: #060e22; --code-border: #1e3a5f;
|
|
39
|
+
}
|
|
40
|
+
* { box-sizing: border-box; margin: 0; padding: 0; }
|
|
41
|
+
body { font-family: 'Inter', sans-serif; background: var(--bg); color: var(--text); min-height: 100vh; transition: background .3s, color .3s; }
|
|
42
|
+
code, pre, .mono { font-family: 'JetBrains Mono', 'Fira Code', monospace; }
|
|
43
|
+
|
|
44
|
+
.site-header { position: sticky; top: 0; z-index: 100; display: flex; align-items: center; justify-content: space-between; padding: 14px 32px; background: var(--surface); border-bottom: 1px solid var(--border); }
|
|
45
|
+
.brand { display: flex; align-items: center; gap: 10px; text-decoration: none; }
|
|
46
|
+
.brand-logo { width: 32px; height: 32px; border-radius: 8px; background: linear-gradient(135deg, #10b981, #059669); display: flex; align-items: center; justify-content: center; font-weight: 800; font-size: 14px; color: #fff; }
|
|
47
|
+
.brand-name { font-weight: 700; font-size: 15px; color: var(--text); }
|
|
48
|
+
.header-actions { display: flex; align-items: center; gap: 12px; }
|
|
49
|
+
.theme-btn { background: var(--surface-2); border: 1px solid var(--border); color: var(--muted); cursor: pointer; border-radius: 8px; padding: 7px 10px; font-size: 16px; }
|
|
50
|
+
|
|
51
|
+
.hero { max-width: 900px; margin: 56px auto 0; padding: 0 24px; text-align: center; }
|
|
52
|
+
.avatar-ring { display: inline-flex; align-items: center; justify-content: center; width: 96px; height: 96px; border-radius: 50%; background: linear-gradient(135deg, #3b82f6, #0ea5e9, #0284c7); margin-bottom: 24px; box-shadow: 0 0 0 6px var(--accent-light); overflow: hidden; }
|
|
53
|
+
.role-chip { display: inline-block; background: var(--accent-light); color: #2563eb; border-radius: 999px; padding: 4px 14px; font-size: 12px; font-weight: 600; letter-spacing: .04em; margin-bottom: 16px; }
|
|
54
|
+
.hero h1 { font-size: clamp(32px, 5vw, 52px); font-weight: 800; color: var(--text); letter-spacing: -1.5px; line-height: 1.1; margin-bottom: 16px; }
|
|
55
|
+
.hero h1 span { color: var(--accent); }
|
|
56
|
+
.hero p { font-size: 17px; color: var(--muted); max-width: 560px; margin: 0 auto 32px; line-height: 1.7; }
|
|
57
|
+
|
|
58
|
+
.section-label { max-width: 900px; margin: 64px auto 0; padding: 0 24px; display: flex; align-items: center; gap: 12px; }
|
|
59
|
+
.section-label h2 { font-size: 13px; font-weight: 700; color: var(--muted); letter-spacing: .08em; text-transform: uppercase; }
|
|
60
|
+
.section-divider { flex: 1; height: 1px; background: var(--border); }
|
|
61
|
+
|
|
62
|
+
.cards-grid { max-width: 900px; margin: 24px auto 0; padding: 0 24px 80px; display: flex; flex-direction: column; gap: 20px; }
|
|
63
|
+
.card { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); box-shadow: var(--shadow); overflow: hidden; transition: box-shadow .2s; }
|
|
64
|
+
.card:hover { box-shadow: var(--shadow-lg); }
|
|
65
|
+
.card-header { display: flex; align-items: flex-start; gap: 16px; padding: 24px; cursor: pointer; user-select: none; }
|
|
66
|
+
.card-icon { width: 48px; height: 48px; border-radius: 12px; display: flex; align-items: center; justify-content: center; font-size: 22px; flex-shrink: 0; }
|
|
67
|
+
.card-meta { flex: 1; min-width: 0; }
|
|
68
|
+
.card-tag { font-size: 11px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; margin-bottom: 6px; }
|
|
69
|
+
.card-title { font-size: 18px; font-weight: 700; color: var(--text); line-height: 1.25; margin-bottom: 6px; }
|
|
70
|
+
.card-subtitle { font-size: 13px; color: var(--muted); }
|
|
71
|
+
.card-toggle { font-size: 22px; color: var(--muted); transition: transform .3s; flex-shrink: 0; align-self: center; }
|
|
72
|
+
.card.open .card-toggle { transform: rotate(90deg); }
|
|
73
|
+
.card-body { display: none; border-top: 1px solid var(--border); padding: 28px; }
|
|
74
|
+
.card.open .card-body { display: block; }
|
|
75
|
+
|
|
76
|
+
.narrative { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 16px; margin-bottom: 28px; }
|
|
77
|
+
@media (max-width: 640px) { .narrative { grid-template-columns: 1fr; } }
|
|
78
|
+
.narrative-step { background: var(--surface-2); border-radius: var(--radius-sm); padding: 16px; }
|
|
79
|
+
.step-label { font-size: 10px; font-weight: 700; letter-spacing: .1em; text-transform: uppercase; color: var(--muted); margin-bottom: 6px; }
|
|
80
|
+
.step-text { font-size: 13px; color: var(--text-2); line-height: 1.6; }
|
|
81
|
+
.artifact-label { font-size: 11px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--muted); margin-bottom: 14px; display: flex; align-items: center; gap: 8px; }
|
|
82
|
+
.artifact-label::before { content: ''; display: block; width: 20px; height: 2px; background: var(--accent); border-radius: 2px; }
|
|
83
|
+
.source-ref { margin-top: 16px; font-size: 12px; color: var(--muted); }
|
|
84
|
+
.source-ref a { color: var(--accent); text-decoration: none; }
|
|
85
|
+
.source-ref a:hover { text-decoration: underline; }
|
|
86
|
+
|
|
87
|
+
/* ══ ARTIFACT 1 — SLO Design Document ══ */
|
|
88
|
+
.slo-dashboard {
|
|
89
|
+
background: var(--surface-2);
|
|
90
|
+
border: 1px solid var(--border);
|
|
91
|
+
border-radius: 14px;
|
|
92
|
+
overflow: hidden;
|
|
93
|
+
}
|
|
94
|
+
.slo-header {
|
|
95
|
+
background: var(--accent);
|
|
96
|
+
padding: 12px 18px;
|
|
97
|
+
display: flex;
|
|
98
|
+
align-items: center;
|
|
99
|
+
justify-content: space-between;
|
|
100
|
+
flex-wrap: wrap;
|
|
101
|
+
gap: 8px;
|
|
102
|
+
}
|
|
103
|
+
.slo-header-title { font-size: 14px; font-weight: 700; color: #fff; }
|
|
104
|
+
.slo-kpis { display: flex; gap: 20px; }
|
|
105
|
+
.slo-kpi { text-align: center; }
|
|
106
|
+
.slo-kpi-val { font-size: 16px; font-weight: 800; color: #fff; }
|
|
107
|
+
.slo-kpi-label { font-size: 10px; color: rgba(255,255,255,.7); text-transform: uppercase; letter-spacing: .05em; }
|
|
108
|
+
.slo-table-header {
|
|
109
|
+
display: grid;
|
|
110
|
+
grid-template-columns: 1.4fr 1fr 1fr 1fr 1.4fr;
|
|
111
|
+
padding: 8px 18px;
|
|
112
|
+
background: var(--surface);
|
|
113
|
+
border-bottom: 1px solid var(--border);
|
|
114
|
+
}
|
|
115
|
+
.slo-table-header span { font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: .06em; color: var(--muted); }
|
|
116
|
+
.slo-row {
|
|
117
|
+
display: grid;
|
|
118
|
+
grid-template-columns: 1.4fr 1fr 1fr 1fr 1.4fr;
|
|
119
|
+
padding: 10px 18px;
|
|
120
|
+
border-bottom: 1px solid var(--border);
|
|
121
|
+
align-items: center;
|
|
122
|
+
}
|
|
123
|
+
.slo-row:last-child { border-bottom: none; }
|
|
124
|
+
.slo-row span { font-size: 12px; color: var(--text-2); }
|
|
125
|
+
.slo-row .row-label { font-weight: 700; color: var(--text); }
|
|
126
|
+
.slo-healthy { color: #10b981; font-weight: 700; }
|
|
127
|
+
.slo-warn { color: #f59e0b; font-weight: 700; }
|
|
128
|
+
.slo-breach { color: #ef4444; font-weight: 700; }
|
|
129
|
+
.slo-summary {
|
|
130
|
+
padding: 12px 18px;
|
|
131
|
+
background: var(--surface);
|
|
132
|
+
border-top: 1px solid var(--border);
|
|
133
|
+
font-size: 12px;
|
|
134
|
+
color: var(--muted);
|
|
135
|
+
line-height: 1.6;
|
|
136
|
+
}
|
|
137
|
+
.slo-summary strong { color: var(--accent); }
|
|
138
|
+
@media (max-width: 600px) {
|
|
139
|
+
.slo-table-header { grid-template-columns: 1.4fr 1fr 1fr; }
|
|
140
|
+
.slo-table-header span:nth-child(n+4) { display: none; }
|
|
141
|
+
.slo-row { grid-template-columns: 1.4fr 1fr 1fr; }
|
|
142
|
+
.slo-row span:nth-child(n+4) { display: none; }
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/* ══ ARTIFACT 2 — Incident Timeline ══ */
|
|
146
|
+
.incident-timeline {
|
|
147
|
+
background: var(--surface-2);
|
|
148
|
+
border: 1px solid var(--border);
|
|
149
|
+
border-radius: 14px;
|
|
150
|
+
overflow: hidden;
|
|
151
|
+
}
|
|
152
|
+
.incident-header {
|
|
153
|
+
background: #dc2626;
|
|
154
|
+
padding: 12px 18px;
|
|
155
|
+
display: flex;
|
|
156
|
+
align-items: center;
|
|
157
|
+
justify-content: space-between;
|
|
158
|
+
flex-wrap: wrap;
|
|
159
|
+
gap: 8px;
|
|
160
|
+
}
|
|
161
|
+
.incident-header-title { font-size: 14px; font-weight: 700; color: #fff; }
|
|
162
|
+
.incident-header-badge { background: rgba(255,255,255,.2); color: #fff; border-radius: 6px; padding: 3px 10px; font-size: 11px; font-weight: 700; }
|
|
163
|
+
.incident-meta { display: flex; gap: 0; border-bottom: 1px solid var(--border); }
|
|
164
|
+
.incident-meta-cell { flex: 1; padding: 10px 14px; border-right: 1px solid var(--border); }
|
|
165
|
+
.incident-meta-cell:last-child { border-right: none; }
|
|
166
|
+
.incident-meta-label { font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: .06em; color: var(--muted); margin-bottom: 3px; }
|
|
167
|
+
.incident-meta-val { font-size: 13px; font-weight: 600; color: var(--text); }
|
|
168
|
+
.incident-events { padding: 4px 0; }
|
|
169
|
+
.incident-event {
|
|
170
|
+
display: flex;
|
|
171
|
+
gap: 14px;
|
|
172
|
+
padding: 10px 18px;
|
|
173
|
+
border-bottom: 1px solid var(--border);
|
|
174
|
+
align-items: flex-start;
|
|
175
|
+
}
|
|
176
|
+
.incident-event:last-child { border-bottom: none; }
|
|
177
|
+
.event-time { font-size: 11px; font-family: 'JetBrains Mono', monospace; color: var(--muted); width: 46px; flex-shrink: 0; margin-top: 2px; }
|
|
178
|
+
.event-dot { width: 8px; height: 8px; border-radius: 50%; margin-top: 5px; flex-shrink: 0; }
|
|
179
|
+
.event-body { flex: 1; }
|
|
180
|
+
.event-action { font-size: 12px; font-weight: 700; color: var(--text); margin-bottom: 2px; }
|
|
181
|
+
.event-detail { font-size: 11px; color: var(--muted); }
|
|
182
|
+
.incident-resolution {
|
|
183
|
+
padding: 12px 18px;
|
|
184
|
+
background: #dcfce7;
|
|
185
|
+
border-top: 1px solid #a7f3d0;
|
|
186
|
+
font-size: 12px;
|
|
187
|
+
color: #15803d;
|
|
188
|
+
font-weight: 600;
|
|
189
|
+
}
|
|
190
|
+
@media (max-width: 600px) {
|
|
191
|
+
.incident-meta { flex-wrap: wrap; }
|
|
192
|
+
.incident-meta-cell { min-width: 50%; }
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/* ══ ARTIFACT 3 — Reliability Review Report ══ */
|
|
196
|
+
.reliability-report {
|
|
197
|
+
background: var(--surface-2);
|
|
198
|
+
border: 1px solid var(--border);
|
|
199
|
+
border-radius: 14px;
|
|
200
|
+
overflow: hidden;
|
|
201
|
+
}
|
|
202
|
+
.reliability-header {
|
|
203
|
+
background: var(--accent);
|
|
204
|
+
padding: 12px 18px;
|
|
205
|
+
display: flex;
|
|
206
|
+
align-items: center;
|
|
207
|
+
justify-content: space-between;
|
|
208
|
+
flex-wrap: wrap;
|
|
209
|
+
gap: 8px;
|
|
210
|
+
}
|
|
211
|
+
.reliability-header-title { font-size: 14px; font-weight: 700; color: #fff; }
|
|
212
|
+
.reliability-kpis { display: flex; gap: 20px; }
|
|
213
|
+
.reliability-kpi { text-align: center; }
|
|
214
|
+
.reliability-kpi-val { font-size: 16px; font-weight: 800; color: #fff; }
|
|
215
|
+
.reliability-kpi-label { font-size: 10px; color: rgba(255,255,255,.7); text-transform: uppercase; letter-spacing: .05em; }
|
|
216
|
+
.finding-row {
|
|
217
|
+
display: flex;
|
|
218
|
+
gap: 12px;
|
|
219
|
+
padding: 12px 18px;
|
|
220
|
+
border-bottom: 1px solid var(--border);
|
|
221
|
+
align-items: flex-start;
|
|
222
|
+
}
|
|
223
|
+
.finding-row:last-child { border-bottom: none; }
|
|
224
|
+
.finding-severity {
|
|
225
|
+
font-size: 10px;
|
|
226
|
+
font-weight: 700;
|
|
227
|
+
padding: 3px 8px;
|
|
228
|
+
border-radius: 999px;
|
|
229
|
+
flex-shrink: 0;
|
|
230
|
+
margin-top: 2px;
|
|
231
|
+
}
|
|
232
|
+
.sev-high { background: #fee2e2; color: #b91c1c; }
|
|
233
|
+
.sev-med { background: #fef9c3; color: #92400e; }
|
|
234
|
+
.sev-low { background: #dcfce7; color: #15803d; }
|
|
235
|
+
.finding-body { flex: 1; }
|
|
236
|
+
.finding-title { font-size: 13px; font-weight: 700; color: var(--text); margin-bottom: 3px; }
|
|
237
|
+
.finding-detail { font-size: 12px; color: var(--muted); }
|
|
238
|
+
.finding-action { font-size: 11px; color: var(--accent); margin-top: 3px; font-weight: 600; }
|
|
239
|
+
.reliability-summary {
|
|
240
|
+
padding: 12px 18px;
|
|
241
|
+
background: var(--surface);
|
|
242
|
+
border-top: 1px solid var(--border);
|
|
243
|
+
font-size: 12px;
|
|
244
|
+
color: var(--muted);
|
|
245
|
+
}
|
|
246
|
+
.reliability-summary strong { color: var(--accent); }
|
|
247
|
+
|
|
248
|
+
/* Footer */
|
|
249
|
+
.portfolio-footer { background: var(--surface); border-top: 1px solid var(--border); padding: 40px 24px; text-align: center; }
|
|
250
|
+
.footer-sub { margin-top: 20px; font-size: 12px; color: var(--muted); }
|
|
251
|
+
.footer-sub a { color: var(--accent); text-decoration: none; }
|
|
252
|
+
|
|
253
|
+
@media (max-width: 640px) {
|
|
254
|
+
.site-header { padding: 12px 16px; }
|
|
255
|
+
.hero { margin-top: 36px; }
|
|
256
|
+
.cards-grid { padding: 0 16px 60px; }
|
|
257
|
+
.card-header { padding: 18px; }
|
|
258
|
+
.card-body { padding: 18px; }
|
|
259
|
+
.section-label { margin-top: 40px; padding: 0 16px; }
|
|
260
|
+
}
|
|
261
|
+
</style>
|
|
262
|
+
</head>
|
|
263
|
+
<body>
|
|
264
|
+
|
|
265
|
+
<header class="site-header">
|
|
266
|
+
<a class="brand" href="/">
|
|
267
|
+
<div class="brand-logo">F</div>
|
|
268
|
+
<span class="brand-name">FRAIM</span>
|
|
269
|
+
</a>
|
|
270
|
+
<div class="header-actions">
|
|
271
|
+
<button class="theme-btn" onclick="toggleTheme()" title="Toggle dark mode">☾</button>
|
|
272
|
+
</div>
|
|
273
|
+
</header>
|
|
274
|
+
|
|
275
|
+
<section class="hero">
|
|
276
|
+
<div class="avatar-ring">
|
|
277
|
+
<img src="https://api.dicebear.com/9.x/notionists/svg?seed=SREYA-site-reliability&backgroundColor=dbeafe&radius=50" width="96" height="96" alt="SREya site reliability engineer avatar" style="border-radius:50%;">
|
|
278
|
+
</div>
|
|
279
|
+
<div class="role-chip">AI Site Reliability Engineer</div>
|
|
280
|
+
<h1>SLOs that reflect user pain.<br>Incidents <span>resolved, not survived</span>.</h1>
|
|
281
|
+
<p>SREya designs error budgets before you need them, runs structured incident command that cuts MTTR in half, and delivers quarterly reliability reviews that give your on-call team a roadmap instead of a burnout spiral.</p>
|
|
282
|
+
</section>
|
|
283
|
+
|
|
284
|
+
<div class="section-label">
|
|
285
|
+
<h2>Selected Work</h2>
|
|
286
|
+
<div class="section-divider"></div>
|
|
287
|
+
</div>
|
|
288
|
+
|
|
289
|
+
<div class="cards-grid">
|
|
290
|
+
|
|
291
|
+
<!-- Card 1: SLO Design -->
|
|
292
|
+
<div class="card open" id="card1">
|
|
293
|
+
<div class="card-header" onclick="toggleCard(1)">
|
|
294
|
+
<div class="card-icon" style="background:#dbeafe;">📡</div>
|
|
295
|
+
<div class="card-meta">
|
|
296
|
+
<div class="card-tag" style="color:#2563eb;">SLO Governance</div>
|
|
297
|
+
<div class="card-title">Error budget burn-rate alert caught a degradation before users noticed.</div>
|
|
298
|
+
<div class="card-subtitle">FRAIM · slo-design-and-implementation · registry/jobs/ai-employee/dev-ops/</div>
|
|
299
|
+
</div>
|
|
300
|
+
<div class="card-toggle">›</div>
|
|
301
|
+
</div>
|
|
302
|
+
<div class="card-body">
|
|
303
|
+
<div class="narrative">
|
|
304
|
+
<div class="narrative-step">
|
|
305
|
+
<div class="step-label">Problem</div>
|
|
306
|
+
<div class="step-text">A B2B SaaS company's on-call team was paged constantly — alerts fired on CPU usage and response time thresholds set years ago by someone who left the company. No SLOs existed. The team was alert-fatigued, and the first time they heard about real user impact was in a support ticket.</div>
|
|
307
|
+
</div>
|
|
308
|
+
<div class="narrative-step">
|
|
309
|
+
<div class="step-label">What SREya Can Build</div>
|
|
310
|
+
<div class="step-text">SREya ran the SLO design process: defined SLIs tied to user journeys (checkout availability, API latency P99, search success rate), set error budgets with a 28-day rolling window, and implemented burn-rate alerting with two windows (1h fast burn, 6h slow burn). Replaced 47 noisy threshold alerts with 6 user-facing SLO alerts.</div>
|
|
311
|
+
</div>
|
|
312
|
+
<div class="narrative-step">
|
|
313
|
+
<div class="step-label">Possible Outcome</div>
|
|
314
|
+
<div class="step-text">Teams that move from threshold alerting to SLO-based burn-rate alerting typically see 60–80% alert volume reduction with higher signal quality. SREya's SLO design can give on-call engineers context — not just a number, but an error budget percentage and time-to-breach — so the first page carries enough information to triage without a call bridge.</div>
|
|
315
|
+
</div>
|
|
316
|
+
</div>
|
|
317
|
+
|
|
318
|
+
<div class="artifact-label">Live Artifact — SLO Error Budget Dashboard · 28-Day Window</div>
|
|
319
|
+
|
|
320
|
+
<div class="slo-dashboard">
|
|
321
|
+
<div class="slo-header">
|
|
322
|
+
<span class="slo-header-title">SLO Error Budget Status · May 2026</span>
|
|
323
|
+
<div class="slo-kpis">
|
|
324
|
+
<div class="slo-kpi">
|
|
325
|
+
<div class="slo-kpi-val">3 SLOs</div>
|
|
326
|
+
<div class="slo-kpi-label">Defined</div>
|
|
327
|
+
</div>
|
|
328
|
+
<div class="slo-kpi">
|
|
329
|
+
<div class="slo-kpi-val">1 Alert</div>
|
|
330
|
+
<div class="slo-kpi-label">Fired</div>
|
|
331
|
+
</div>
|
|
332
|
+
</div>
|
|
333
|
+
</div>
|
|
334
|
+
<div class="slo-table-header">
|
|
335
|
+
<span>SLO</span>
|
|
336
|
+
<span>Target</span>
|
|
337
|
+
<span>Current</span>
|
|
338
|
+
<span>Budget Used</span>
|
|
339
|
+
<span>Status</span>
|
|
340
|
+
</div>
|
|
341
|
+
<div class="slo-row">
|
|
342
|
+
<span class="row-label">Checkout Avail.</span>
|
|
343
|
+
<span>99.9%</span>
|
|
344
|
+
<span>99.93%</span>
|
|
345
|
+
<span>28%</span>
|
|
346
|
+
<span class="slo-healthy">● HEALTHY</span>
|
|
347
|
+
</div>
|
|
348
|
+
<div class="slo-row">
|
|
349
|
+
<span class="row-label">API Latency P99</span>
|
|
350
|
+
<span>< 400ms</span>
|
|
351
|
+
<span>380ms</span>
|
|
352
|
+
<span class="slo-warn">71%</span>
|
|
353
|
+
<span class="slo-warn">● BURNING FAST</span>
|
|
354
|
+
</div>
|
|
355
|
+
<div class="slo-row">
|
|
356
|
+
<span class="row-label">Search Success</span>
|
|
357
|
+
<span>99.5%</span>
|
|
358
|
+
<span>99.6%</span>
|
|
359
|
+
<span>12%</span>
|
|
360
|
+
<span class="slo-healthy">● HEALTHY</span>
|
|
361
|
+
</div>
|
|
362
|
+
<div class="slo-summary">
|
|
363
|
+
<strong>API latency burn-rate alert fired</strong> at 18:43 UTC — 6h window exceeded 10× burn threshold. Paged IC before any user-visible impact. Resolved in 22 minutes. Error budget replenished within 4 hours.
|
|
364
|
+
</div>
|
|
365
|
+
</div>
|
|
366
|
+
|
|
367
|
+
<div class="source-ref">
|
|
368
|
+
📎 Source: <a href="#">FRAIM · slo-design-and-implementation · registry/jobs/ai-employee/dev-ops/slo-design-and-implementation.md</a>
|
|
369
|
+
</div>
|
|
370
|
+
</div>
|
|
371
|
+
</div>
|
|
372
|
+
|
|
373
|
+
<!-- Card 2: Incident Response -->
|
|
374
|
+
<div class="card" id="card2">
|
|
375
|
+
<div class="card-header" onclick="toggleCard(2)">
|
|
376
|
+
<div class="card-icon" style="background:#fee2e2;">🚨</div>
|
|
377
|
+
<div class="card-meta">
|
|
378
|
+
<div class="card-tag" style="color:#dc2626;">Incident Command</div>
|
|
379
|
+
<div class="card-title">SEV2 resolved in 28 minutes. Blameless postmortem same day.</div>
|
|
380
|
+
<div class="card-subtitle">FRAIM · incident-response · registry/jobs/ai-employee/dev-ops/</div>
|
|
381
|
+
</div>
|
|
382
|
+
<div class="card-toggle">›</div>
|
|
383
|
+
</div>
|
|
384
|
+
<div class="card-body">
|
|
385
|
+
<div class="narrative">
|
|
386
|
+
<div class="narrative-step">
|
|
387
|
+
<div class="step-label">Problem</div>
|
|
388
|
+
<div class="step-text">A startup's incident management was ad-hoc: whoever noticed the problem became the IC by default, Slack filled with overlapping hypotheses, and status updates went out 40 minutes after the incident started. Customers were finding out from Twitter, not from the status page.</div>
|
|
389
|
+
</div>
|
|
390
|
+
<div class="narrative-step">
|
|
391
|
+
<div class="step-label">What SREya Can Build</div>
|
|
392
|
+
<div class="step-text">SREya ran structured incident command: classified the incident as SEV2 in under 2 minutes using the severity matrix, assigned roles (IC, Comms Lead, Tech Lead, Scribe), opened a dedicated incident channel, posted a status page update within 5 minutes, and drove timeboxed investigation rounds — 10 minutes per hypothesis. Closed the incident bridge when resolution was confirmed.</div>
|
|
393
|
+
</div>
|
|
394
|
+
<div class="narrative-step">
|
|
395
|
+
<div class="step-label">Possible Outcome</div>
|
|
396
|
+
<div class="step-text">Structured incident command with SREya typically reduces MTTR by 40–60% — not because the debugging is different, but because the coordination overhead is eliminated. SREya's blameless postmortem same-day policy means action items are captured while context is fresh, and the team can move forward without a blame culture creating the next incident.</div>
|
|
397
|
+
</div>
|
|
398
|
+
</div>
|
|
399
|
+
|
|
400
|
+
<div class="artifact-label">Live Artifact — Incident Timeline · INC-2847 (SEV2)</div>
|
|
401
|
+
|
|
402
|
+
<div class="incident-timeline">
|
|
403
|
+
<div class="incident-header">
|
|
404
|
+
<span class="incident-header-title">INC-2847 · Payment Service Degradation · SEV2</span>
|
|
405
|
+
<span class="incident-header-badge">RESOLVED 28 MIN</span>
|
|
406
|
+
</div>
|
|
407
|
+
<div class="incident-meta">
|
|
408
|
+
<div class="incident-meta-cell">
|
|
409
|
+
<div class="incident-meta-label">IC</div>
|
|
410
|
+
<div class="incident-meta-val">SREya</div>
|
|
411
|
+
</div>
|
|
412
|
+
<div class="incident-meta-cell">
|
|
413
|
+
<div class="incident-meta-label">Tech Lead</div>
|
|
414
|
+
<div class="incident-meta-val">On-call Eng</div>
|
|
415
|
+
</div>
|
|
416
|
+
<div class="incident-meta-cell">
|
|
417
|
+
<div class="incident-meta-label">Comms Lead</div>
|
|
418
|
+
<div class="incident-meta-val">CX Lead</div>
|
|
419
|
+
</div>
|
|
420
|
+
<div class="incident-meta-cell">
|
|
421
|
+
<div class="incident-meta-label">Impact</div>
|
|
422
|
+
<div class="incident-meta-val">~340 users</div>
|
|
423
|
+
</div>
|
|
424
|
+
</div>
|
|
425
|
+
<div class="incident-events">
|
|
426
|
+
<div class="incident-event">
|
|
427
|
+
<span class="event-time">14:02</span>
|
|
428
|
+
<div class="event-dot" style="background:#ef4444;"></div>
|
|
429
|
+
<div class="event-body">
|
|
430
|
+
<div class="event-action">SLO alert fired — API P99 burn rate 18× over 1h window</div>
|
|
431
|
+
<div class="event-detail">Payment service latency spike detected. IC role assigned.</div>
|
|
432
|
+
</div>
|
|
433
|
+
</div>
|
|
434
|
+
<div class="incident-event">
|
|
435
|
+
<span class="event-time">14:04</span>
|
|
436
|
+
<div class="event-dot" style="background:#f59e0b;"></div>
|
|
437
|
+
<div class="event-body">
|
|
438
|
+
<div class="event-action">Severity classified: SEV2 · Roles assigned</div>
|
|
439
|
+
<div class="event-detail">Status page incident opened. Customer comms drafted.</div>
|
|
440
|
+
</div>
|
|
441
|
+
</div>
|
|
442
|
+
<div class="incident-event">
|
|
443
|
+
<span class="event-time">14:07</span>
|
|
444
|
+
<div class="event-dot" style="background:#3b82f6;"></div>
|
|
445
|
+
<div class="event-body">
|
|
446
|
+
<div class="event-action">Status page update published — "Investigating payment latency"</div>
|
|
447
|
+
<div class="event-detail">5 min from alert to customer-visible acknowledgment.</div>
|
|
448
|
+
</div>
|
|
449
|
+
</div>
|
|
450
|
+
<div class="incident-event">
|
|
451
|
+
<span class="event-time">14:17</span>
|
|
452
|
+
<div class="event-dot" style="background:#f59e0b;"></div>
|
|
453
|
+
<div class="event-body">
|
|
454
|
+
<div class="event-action">Root cause identified: DB connection pool exhausted</div>
|
|
455
|
+
<div class="event-detail">New deployment at 13:55 introduced a connection leak. Rollback initiated.</div>
|
|
456
|
+
</div>
|
|
457
|
+
</div>
|
|
458
|
+
<div class="incident-event">
|
|
459
|
+
<span class="event-time">14:30</span>
|
|
460
|
+
<div class="event-dot" style="background:#10b981;"></div>
|
|
461
|
+
<div class="event-body">
|
|
462
|
+
<div class="event-action">Rollback complete · Latency nominal · SLO healthy</div>
|
|
463
|
+
<div class="event-detail">Status page resolved. Blameless postmortem scheduled 16:00 same day.</div>
|
|
464
|
+
</div>
|
|
465
|
+
</div>
|
|
466
|
+
</div>
|
|
467
|
+
<div class="incident-resolution">✓ Resolved in 28 minutes · Blameless postmortem completed 4 hours later · 3 action items tracked to completion</div>
|
|
468
|
+
</div>
|
|
469
|
+
|
|
470
|
+
<div class="source-ref">
|
|
471
|
+
📎 Source: <a href="#">FRAIM · incident-response · registry/jobs/ai-employee/dev-ops/incident-response.md</a>
|
|
472
|
+
</div>
|
|
473
|
+
</div>
|
|
474
|
+
</div>
|
|
475
|
+
|
|
476
|
+
<!-- Card 3: Reliability Review -->
|
|
477
|
+
<div class="card" id="card3">
|
|
478
|
+
<div class="card-header" onclick="toggleCard(3)">
|
|
479
|
+
<div class="card-icon" style="background:#dbeafe;">🔍</div>
|
|
480
|
+
<div class="card-meta">
|
|
481
|
+
<div class="card-tag" style="color:#2563eb;">Reliability Audit</div>
|
|
482
|
+
<div class="card-title">Three runbook gaps closed. On-call rotation stabilized within 6 weeks.</div>
|
|
483
|
+
<div class="card-subtitle">FRAIM · reliability-review · registry/jobs/ai-employee/dev-ops/</div>
|
|
484
|
+
</div>
|
|
485
|
+
<div class="card-toggle">›</div>
|
|
486
|
+
</div>
|
|
487
|
+
<div class="card-body">
|
|
488
|
+
<div class="narrative">
|
|
489
|
+
<div class="narrative-step">
|
|
490
|
+
<div class="step-label">Problem</div>
|
|
491
|
+
<div class="step-text">A 30-person engineering team had 4 engineers on rotation and 2 of them threatening to quit. Runbooks were outdated or missing for 40% of alert types. Every on-call shift involved at least one "this runbook doesn't match what I'm seeing" moment. The team was burning error budget faster than they were shipping features.</div>
|
|
492
|
+
</div>
|
|
493
|
+
<div class="narrative-step">
|
|
494
|
+
<div class="step-label">What SREya Can Build</div>
|
|
495
|
+
<div class="step-text">SREya ran a quarterly reliability review: audited all SLO performance against error budgets, reviewed all runbooks against recent incident timelines to find gaps, scored each gap by frequency × impact, and produced a prioritized action plan. Identified 3 runbook gaps responsible for 64% of on-call escalations and recommended rotation changes to reduce per-engineer burden.</div>
|
|
496
|
+
</div>
|
|
497
|
+
<div class="narrative-step">
|
|
498
|
+
<div class="step-label">Possible Outcome</div>
|
|
499
|
+
<div class="step-text">A quarterly reliability review with SREya gives engineering leadership a defensible view of on-call health — not just anecdotal "it's bad". Teams that close the top 3 runbook gaps typically see escalation frequency drop by 50–70%, and rotation stabilization follows naturally when on-call is predictable rather than chaotic.</div>
|
|
500
|
+
</div>
|
|
501
|
+
</div>
|
|
502
|
+
|
|
503
|
+
<div class="artifact-label">Live Artifact — Q2 2026 Reliability Review · Action Plan</div>
|
|
504
|
+
|
|
505
|
+
<div class="reliability-report">
|
|
506
|
+
<div class="reliability-header">
|
|
507
|
+
<span class="reliability-header-title">Reliability Review · Q2 2026 · Priority Findings</span>
|
|
508
|
+
<div class="reliability-kpis">
|
|
509
|
+
<div class="reliability-kpi">
|
|
510
|
+
<div class="reliability-kpi-val">8 findings</div>
|
|
511
|
+
<div class="reliability-kpi-label">Total</div>
|
|
512
|
+
</div>
|
|
513
|
+
<div class="reliability-kpi">
|
|
514
|
+
<div class="reliability-kpi-val">3 HIGH</div>
|
|
515
|
+
<div class="reliability-kpi-label">Priority</div>
|
|
516
|
+
</div>
|
|
517
|
+
</div>
|
|
518
|
+
</div>
|
|
519
|
+
<div class="finding-row">
|
|
520
|
+
<span class="finding-severity sev-high">HIGH</span>
|
|
521
|
+
<div class="finding-body">
|
|
522
|
+
<div class="finding-title">No runbook for DB failover</div>
|
|
523
|
+
<div class="finding-detail">Triggered in 4 of last 6 incidents. Average escalation adds 18 minutes to MTTR.</div>
|
|
524
|
+
<div class="finding-action">→ Author failover runbook; test in staging by June 15</div>
|
|
525
|
+
</div>
|
|
526
|
+
</div>
|
|
527
|
+
<div class="finding-row">
|
|
528
|
+
<span class="finding-severity sev-high">HIGH</span>
|
|
529
|
+
<div class="finding-body">
|
|
530
|
+
<div class="finding-title">SLO targets pre-date current traffic patterns</div>
|
|
531
|
+
<div class="finding-detail">P99 latency SLO set at 400ms. Current P95 baseline is 310ms. Targets stale since Jan 2025.</div>
|
|
532
|
+
<div class="finding-action">→ Recalibrate SLOs against 90-day traffic baseline</div>
|
|
533
|
+
</div>
|
|
534
|
+
</div>
|
|
535
|
+
<div class="finding-row">
|
|
536
|
+
<span class="finding-severity sev-high">HIGH</span>
|
|
537
|
+
<div class="finding-body">
|
|
538
|
+
<div class="finding-title">Payment service has no on-call owner documented</div>
|
|
539
|
+
<div class="finding-detail">Last 3 incidents required cross-team escalation because ownership was unclear.</div>
|
|
540
|
+
<div class="finding-action">→ Assign explicit service ownership; update PagerDuty routing</div>
|
|
541
|
+
</div>
|
|
542
|
+
</div>
|
|
543
|
+
<div class="finding-row">
|
|
544
|
+
<span class="finding-severity sev-med">MED</span>
|
|
545
|
+
<div class="finding-body">
|
|
546
|
+
<div class="finding-title">Deployment rollback procedure not documented</div>
|
|
547
|
+
<div class="finding-detail">INC-2847 demonstrated the gap; rollback worked but took 13 minutes to initiate.</div>
|
|
548
|
+
<div class="finding-action">→ Add rollback runbook with 5-minute SLA target</div>
|
|
549
|
+
</div>
|
|
550
|
+
</div>
|
|
551
|
+
<div class="finding-row">
|
|
552
|
+
<span class="finding-severity sev-low">LOW</span>
|
|
553
|
+
<div class="finding-body">
|
|
554
|
+
<div class="finding-title">Postmortem action items 40% completed within 30 days</div>
|
|
555
|
+
<div class="finding-detail">Action items created but not tracked to completion. No owner assignment on 6 of 15 items.</div>
|
|
556
|
+
<div class="finding-action">→ Move postmortem tracking to Linear with weekly triage</div>
|
|
557
|
+
</div>
|
|
558
|
+
</div>
|
|
559
|
+
<div class="reliability-summary">
|
|
560
|
+
<strong>Projected impact:</strong> Closing top 3 findings estimated to reduce on-call escalation frequency by 62% and cut MTTR by 24 minutes on average · Full action plan with owners and due dates included
|
|
561
|
+
</div>
|
|
562
|
+
</div>
|
|
563
|
+
|
|
564
|
+
<div class="source-ref">
|
|
565
|
+
📎 Source: <a href="#">FRAIM · reliability-review · registry/jobs/ai-employee/dev-ops/reliability-review.md</a>
|
|
566
|
+
</div>
|
|
567
|
+
</div>
|
|
568
|
+
</div>
|
|
569
|
+
|
|
570
|
+
</div>
|
|
571
|
+
|
|
572
|
+
<footer class="portfolio-footer">
|
|
573
|
+
<div class="footer-sub">
|
|
574
|
+
Part of the <a href="/">FRAIM</a> · 20 AI employees available ·
|
|
575
|
+
<a href="/">Back to FRAIM</a>
|
|
576
|
+
</div>
|
|
577
|
+
</footer>
|
|
578
|
+
|
|
579
|
+
<script>
|
|
580
|
+
function toggleTheme() {
|
|
581
|
+
const html = document.documentElement;
|
|
582
|
+
const isDark = html.getAttribute('data-theme') === 'dark';
|
|
583
|
+
html.setAttribute('data-theme', isDark ? 'light' : 'dark');
|
|
584
|
+
document.querySelector('.theme-btn').textContent = isDark ? '☾' : '☀';
|
|
585
|
+
}
|
|
586
|
+
if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
|
|
587
|
+
document.documentElement.setAttribute('data-theme', 'dark');
|
|
588
|
+
document.querySelector('.theme-btn').textContent = '☀';
|
|
589
|
+
}
|
|
590
|
+
function toggleCard(num) {
|
|
591
|
+
const card = document.getElementById('card' + num);
|
|
592
|
+
const isOpen = card.classList.contains('open');
|
|
593
|
+
document.querySelectorAll('.card').forEach(c => c.classList.remove('open'));
|
|
594
|
+
if (!isOpen) { card.classList.add('open'); card.scrollIntoView({ behavior: 'smooth', block: 'nearest' }); }
|
|
595
|
+
}
|
|
596
|
+
</script>
|
|
597
|
+
|
|
598
|
+
</body>
|
|
599
|
+
</html>
|