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,523 @@
|
|
|
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>AshLey · AI Executive Assistant · 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: #f59e0b;
|
|
13
|
+
--accent-2: #d97706;
|
|
14
|
+
--accent-light: #fef3c7;
|
|
15
|
+
--text: #0a2240;
|
|
16
|
+
--text-2: #334155;
|
|
17
|
+
--muted: #64748b;
|
|
18
|
+
--bg: #fffbeb;
|
|
19
|
+
--surface: #ffffff;
|
|
20
|
+
--surface-2: #f8fafc;
|
|
21
|
+
--border: #e2e8f0;
|
|
22
|
+
--shadow: 0 4px 24px rgba(10,34,64,.08);
|
|
23
|
+
--shadow-lg: 0 12px 40px rgba(10,34,64,.14);
|
|
24
|
+
--radius: 18px;
|
|
25
|
+
--radius-sm: 10px;
|
|
26
|
+
--green: #10b981;
|
|
27
|
+
--purple: #8b5cf6;
|
|
28
|
+
--red: #ef4444;
|
|
29
|
+
--code-bg: #0f172a;
|
|
30
|
+
--code-border: #1e293b;
|
|
31
|
+
}
|
|
32
|
+
[data-theme="dark"] {
|
|
33
|
+
--text: #e2e8f0; --text-2: #cbd5e1; --muted: #94a3b8;
|
|
34
|
+
--bg: #1c1409; --surface: #221a07; --surface-2: #2a200a;
|
|
35
|
+
--border: #3d2e0f; --shadow: 0 4px 24px rgba(0,0,0,.35);
|
|
36
|
+
--shadow-lg: 0 12px 40px rgba(0,0,0,.5); --accent-light: #451a03;
|
|
37
|
+
--code-bg: #0a0800; --code-border: #221a07;
|
|
38
|
+
}
|
|
39
|
+
* { box-sizing: border-box; margin: 0; padding: 0; }
|
|
40
|
+
body { font-family: 'Inter', sans-serif; background: var(--bg); color: var(--text); min-height: 100vh; transition: background .3s, color .3s; }
|
|
41
|
+
code, pre, .mono { font-family: 'JetBrains Mono', 'Fira Code', monospace; }
|
|
42
|
+
|
|
43
|
+
.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); }
|
|
44
|
+
.brand { display: flex; align-items: center; gap: 10px; text-decoration: none; }
|
|
45
|
+
.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; }
|
|
46
|
+
.brand-name { font-weight: 700; font-size: 15px; color: var(--text); }
|
|
47
|
+
.header-actions { display: flex; align-items: center; gap: 12px; }
|
|
48
|
+
.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; }
|
|
49
|
+
|
|
50
|
+
.hero { max-width: 900px; margin: 56px auto 0; padding: 0 24px; text-align: center; }
|
|
51
|
+
.avatar-ring { display: inline-flex; align-items: center; justify-content: center; width: 96px; height: 96px; border-radius: 50%; background: linear-gradient(135deg, #f59e0b, #ef4444, #ec4899); margin-bottom: 24px; box-shadow: 0 0 0 6px var(--accent-light); overflow: hidden; }
|
|
52
|
+
.avatar-initials { font-size: 28px; font-weight: 800; color: #fff; letter-spacing: -1px; font-family: 'JetBrains Mono', monospace; }
|
|
53
|
+
.role-chip { display: inline-block; background: var(--accent-light); color: var(--accent-2); 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
|
+
.card-context { font-size: 13px; color: var(--muted); font-style: italic; margin-bottom: 20px; line-height: 1.6; border-left: 3px solid var(--accent-light); padding-left: 14px; }
|
|
77
|
+
|
|
78
|
+
.narrative { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 16px; margin-bottom: 28px; }
|
|
79
|
+
@media (max-width: 640px) { .narrative { grid-template-columns: 1fr; } }
|
|
80
|
+
.narrative-step { background: var(--surface-2); border-radius: var(--radius-sm); padding: 16px; }
|
|
81
|
+
.step-label { font-size: 10px; font-weight: 700; letter-spacing: .1em; text-transform: uppercase; color: var(--muted); margin-bottom: 6px; }
|
|
82
|
+
.step-text { font-size: 13px; color: var(--text-2); line-height: 1.6; }
|
|
83
|
+
.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; }
|
|
84
|
+
.artifact-label::before { content: ''; display: block; width: 20px; height: 2px; background: var(--accent); border-radius: 2px; }
|
|
85
|
+
.source-ref { margin-top: 16px; font-size: 12px; color: var(--muted); }
|
|
86
|
+
.source-ref a { color: var(--accent); text-decoration: none; }
|
|
87
|
+
.source-ref a:hover { text-decoration: underline; }
|
|
88
|
+
|
|
89
|
+
/* ══ ARTIFACT 1 — Executive Briefing Panel ══ */
|
|
90
|
+
.briefing-panel {
|
|
91
|
+
background: #0f172a;
|
|
92
|
+
border-radius: 14px;
|
|
93
|
+
overflow: hidden;
|
|
94
|
+
border: 1px solid #1e293b;
|
|
95
|
+
}
|
|
96
|
+
.briefing-topbar {
|
|
97
|
+
background: #1e293b;
|
|
98
|
+
padding: 12px 18px;
|
|
99
|
+
display: flex; align-items: center; justify-content: space-between;
|
|
100
|
+
border-bottom: 1px solid #334155;
|
|
101
|
+
}
|
|
102
|
+
.briefing-topbar-title { font-size: 13px; font-weight: 600; color: #e2e8f0; font-family: 'JetBrains Mono', monospace; }
|
|
103
|
+
.briefing-topbar-date { font-size: 11px; color: #64748b; }
|
|
104
|
+
.briefing-items { padding: 16px; display: flex; flex-direction: column; gap: 10px; }
|
|
105
|
+
.briefing-item {
|
|
106
|
+
background: #1e293b;
|
|
107
|
+
border-radius: 10px;
|
|
108
|
+
padding: 14px 16px;
|
|
109
|
+
display: flex; align-items: flex-start; gap: 12px;
|
|
110
|
+
border: 1px solid #334155;
|
|
111
|
+
}
|
|
112
|
+
.priority-dot { width: 10px; height: 10px; border-radius: 50%; flex-shrink: 0; margin-top: 4px; }
|
|
113
|
+
.briefing-item-text { flex: 1; font-size: 13px; color: #cbd5e1; line-height: 1.5; }
|
|
114
|
+
.briefing-actions { display: flex; gap: 6px; flex-shrink: 0; flex-wrap: wrap; }
|
|
115
|
+
.baction-btn {
|
|
116
|
+
font-size: 11px; font-weight: 600; padding: 5px 10px; border-radius: 6px;
|
|
117
|
+
border: 1px solid #334155; background: #0f172a; color: #94a3b8;
|
|
118
|
+
cursor: pointer; transition: all .15s; white-space: nowrap;
|
|
119
|
+
}
|
|
120
|
+
.baction-btn:hover { border-color: #64748b; color: #e2e8f0; }
|
|
121
|
+
.baction-btn.decide { border-color: #166534; color: #4ade80; }
|
|
122
|
+
.baction-btn.decide:hover { background: #166534; color: #fff; }
|
|
123
|
+
.baction-btn.decided { background: #166534; color: #4ade80; border-color: #166534; }
|
|
124
|
+
|
|
125
|
+
/* ══ ARTIFACT 2 — Voice Scheduling ══ */
|
|
126
|
+
.voice-card {
|
|
127
|
+
background: var(--surface);
|
|
128
|
+
border: 1px solid var(--border);
|
|
129
|
+
border-radius: 14px;
|
|
130
|
+
padding: 28px 24px;
|
|
131
|
+
text-align: center;
|
|
132
|
+
}
|
|
133
|
+
.mic-btn {
|
|
134
|
+
width: 80px; height: 80px; border-radius: 50%;
|
|
135
|
+
background: linear-gradient(135deg, #f59e0b, #ef4444);
|
|
136
|
+
display: inline-flex; align-items: center; justify-content: center;
|
|
137
|
+
font-size: 32px;
|
|
138
|
+
box-shadow: 0 0 0 0 rgba(245,158,11,.5);
|
|
139
|
+
animation: pulse-mic 2s infinite;
|
|
140
|
+
cursor: pointer;
|
|
141
|
+
border: none;
|
|
142
|
+
margin-bottom: 20px;
|
|
143
|
+
}
|
|
144
|
+
@keyframes pulse-mic {
|
|
145
|
+
0% { box-shadow: 0 0 0 0 rgba(245,158,11,.5); }
|
|
146
|
+
60% { box-shadow: 0 0 0 18px rgba(245,158,11,0); }
|
|
147
|
+
100% { box-shadow: 0 0 0 0 rgba(245,158,11,0); }
|
|
148
|
+
}
|
|
149
|
+
.waveform { display: flex; align-items: flex-end; justify-content: center; gap: 4px; height: 36px; margin-bottom: 14px; }
|
|
150
|
+
.wave-bar {
|
|
151
|
+
width: 5px; border-radius: 3px;
|
|
152
|
+
background: var(--accent);
|
|
153
|
+
animation: wave-bounce 1s ease-in-out infinite;
|
|
154
|
+
}
|
|
155
|
+
.wave-bar:nth-child(1) { animation-delay: 0s; }
|
|
156
|
+
.wave-bar:nth-child(2) { animation-delay: .15s; }
|
|
157
|
+
.wave-bar:nth-child(3) { animation-delay: .3s; }
|
|
158
|
+
.wave-bar:nth-child(4) { animation-delay: .15s; }
|
|
159
|
+
.wave-bar:nth-child(5) { animation-delay: 0s; }
|
|
160
|
+
@keyframes wave-bounce {
|
|
161
|
+
0%, 100% { height: 8px; opacity: .5; }
|
|
162
|
+
50% { height: 30px; opacity: 1; }
|
|
163
|
+
}
|
|
164
|
+
.voice-status { font-size: 14px; font-weight: 600; color: var(--text-2); margin-bottom: 18px; min-height: 22px; }
|
|
165
|
+
.slot-chips { display: flex; justify-content: center; gap: 10px; flex-wrap: wrap; margin-bottom: 10px; }
|
|
166
|
+
.slot-chip {
|
|
167
|
+
padding: 8px 16px; border-radius: 999px;
|
|
168
|
+
border: 2px solid var(--border); background: var(--surface-2);
|
|
169
|
+
font-size: 13px; font-weight: 600; color: var(--text-2);
|
|
170
|
+
cursor: pointer; transition: all .2s;
|
|
171
|
+
}
|
|
172
|
+
.slot-chip:hover { border-color: var(--accent); color: var(--accent); }
|
|
173
|
+
.slot-chip.selected { background: var(--accent); border-color: var(--accent); color: #fff; }
|
|
174
|
+
.invite-sent { font-size: 12px; font-weight: 700; color: var(--accent); min-height: 20px; margin-top: 6px; }
|
|
175
|
+
|
|
176
|
+
/* ══ ARTIFACT 3 — Meeting Relevance Table ══ */
|
|
177
|
+
.rel-table-wrap {
|
|
178
|
+
border: 1px solid var(--border);
|
|
179
|
+
border-radius: 14px;
|
|
180
|
+
overflow: hidden;
|
|
181
|
+
}
|
|
182
|
+
.rel-table { width: 100%; border-collapse: collapse; font-size: 13px; }
|
|
183
|
+
.rel-table th {
|
|
184
|
+
background: var(--surface-2);
|
|
185
|
+
padding: 10px 14px;
|
|
186
|
+
text-align: left;
|
|
187
|
+
font-size: 10px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase;
|
|
188
|
+
color: var(--muted);
|
|
189
|
+
border-bottom: 1px solid var(--border);
|
|
190
|
+
}
|
|
191
|
+
.rel-table td { padding: 11px 14px; border-bottom: 1px solid var(--border); color: var(--text-2); }
|
|
192
|
+
.rel-table tr:last-child td { border-bottom: none; }
|
|
193
|
+
.rel-table tr:hover td { background: var(--surface-2); }
|
|
194
|
+
.score-mono { font-family: 'JetBrains Mono', monospace; font-weight: 700; font-size: 14px; }
|
|
195
|
+
.rec-badge { display: inline-block; padding: 3px 10px; border-radius: 999px; font-size: 11px; font-weight: 700; letter-spacing: .04em; }
|
|
196
|
+
.badge-attend { background: #dcfce7; color: #166534; }
|
|
197
|
+
.badge-delegate { background: #fef3c7; color: #92400e; }
|
|
198
|
+
.badge-skip { background: #f1f5f9; color: #64748b; }
|
|
199
|
+
[data-theme="dark"] .badge-attend { background: #14532d; color: #4ade80; }
|
|
200
|
+
[data-theme="dark"] .badge-delegate { background: #451a03; color: #fbbf24; }
|
|
201
|
+
[data-theme="dark"] .badge-skip { background: #1e293b; color: #94a3b8; }
|
|
202
|
+
|
|
203
|
+
/* Footer */
|
|
204
|
+
.portfolio-footer { background: var(--surface); border-top: 1px solid var(--border); padding: 40px 24px; text-align: center; }
|
|
205
|
+
.footer-sub { margin-top: 20px; font-size: 12px; color: var(--muted); }
|
|
206
|
+
.footer-sub a { color: var(--accent); text-decoration: none; }
|
|
207
|
+
|
|
208
|
+
@media (max-width: 640px) {
|
|
209
|
+
.site-header { padding: 12px 16px; }
|
|
210
|
+
.hero { margin-top: 36px; }
|
|
211
|
+
.cards-grid { padding: 0 16px 60px; }
|
|
212
|
+
.card-header { padding: 18px; }
|
|
213
|
+
.card-body { padding: 18px; }
|
|
214
|
+
.section-label { margin-top: 40px; padding: 0 16px; }
|
|
215
|
+
.briefing-actions { flex-direction: column; }
|
|
216
|
+
.rel-table th, .rel-table td { padding: 8px 10px; }
|
|
217
|
+
}
|
|
218
|
+
</style>
|
|
219
|
+
</head>
|
|
220
|
+
<body>
|
|
221
|
+
|
|
222
|
+
<header class="site-header">
|
|
223
|
+
<a class="brand" href="/">
|
|
224
|
+
<div class="brand-logo">F</div>
|
|
225
|
+
<span class="brand-name">FRAIM</span>
|
|
226
|
+
</a>
|
|
227
|
+
<div class="header-actions">
|
|
228
|
+
<button class="theme-btn" onclick="toggleTheme()" title="Toggle dark mode">☾</button>
|
|
229
|
+
</div>
|
|
230
|
+
</header>
|
|
231
|
+
|
|
232
|
+
<section class="hero">
|
|
233
|
+
<div class="avatar-ring">
|
|
234
|
+
<img src="https://api.dicebear.com/9.x/notionists/svg?seed=Ashley-assistant&backgroundColor=fde68a&radius=50" width="96" height="96" alt="Ashley-assistant avatar" style="border-radius:50%;">
|
|
235
|
+
</div>
|
|
236
|
+
<div class="role-chip">AI Executive Assistant</div>
|
|
237
|
+
<h1>Your calendar cleared.<br>Your decisions <span>ready</span>.</h1>
|
|
238
|
+
<p>Your calendar cleared. Your decisions ready. Your meetings worth attending.</p>
|
|
239
|
+
</section>
|
|
240
|
+
|
|
241
|
+
<div class="section-label">
|
|
242
|
+
<h2>Selected Work</h2>
|
|
243
|
+
<div class="section-divider"></div>
|
|
244
|
+
</div>
|
|
245
|
+
|
|
246
|
+
<div class="cards-grid">
|
|
247
|
+
|
|
248
|
+
<!-- Card 1: Executive Briefing Dashboard -->
|
|
249
|
+
<div class="card open" id="card1">
|
|
250
|
+
<div class="card-header" onclick="toggleCard(1)">
|
|
251
|
+
<div class="card-icon" style="background:#fef3c7;">📊</div>
|
|
252
|
+
<div class="card-meta">
|
|
253
|
+
<div class="card-tag" style="color:#f59e0b;">Executive Intelligence</div>
|
|
254
|
+
<div class="card-title">Morning Briefing to Action Center</div>
|
|
255
|
+
<div class="card-subtitle">Ashley-Calendar-AI · feat/1150-dashboard-improvements</div>
|
|
256
|
+
</div>
|
|
257
|
+
<div class="card-toggle">›</div>
|
|
258
|
+
</div>
|
|
259
|
+
<div class="card-body">
|
|
260
|
+
<div class="card-context">A Fortune-500 VP was drowning in 47 unread briefings — weekly summaries that required 30 minutes to parse before any meeting.</div>
|
|
261
|
+
|
|
262
|
+
<div class="narrative">
|
|
263
|
+
<div class="narrative-step">
|
|
264
|
+
<div class="step-label">Problem</div>
|
|
265
|
+
<div class="step-text">The briefing was a data dump: raw calendar blocks, disconnected priorities, no clear "what matters today." Executives were reading the same content twice — once in the briefing, once again when they needed to act on it.</div>
|
|
266
|
+
</div>
|
|
267
|
+
<div class="narrative-step">
|
|
268
|
+
<div class="step-label">What AshLey Did</div>
|
|
269
|
+
<div class="step-text">AshLey redesigned the briefing surface as an action center. Each briefing item has a three-tier decision prompt: defer, delegate, or decide now. Priority scores are surfaced from meeting attendee seniority, deadline proximity, and topic recurrence. The redesigned card auto-collapses resolved items.</div>
|
|
270
|
+
</div>
|
|
271
|
+
<div class="narrative-step">
|
|
272
|
+
<div class="step-label">The Outcome</div>
|
|
273
|
+
<div class="step-text">Time-to-first-action dropped from 28 minutes to under 4. The VP's EA reported 60% fewer "what should I focus on?" morning messages.</div>
|
|
274
|
+
</div>
|
|
275
|
+
</div>
|
|
276
|
+
|
|
277
|
+
<div class="artifact-label">Live Artifact — Morning Briefing Action Center</div>
|
|
278
|
+
|
|
279
|
+
<div class="briefing-panel">
|
|
280
|
+
<div class="briefing-topbar">
|
|
281
|
+
<span class="briefing-topbar-title">Morning Briefing — May 21, 2026</span>
|
|
282
|
+
<span class="briefing-topbar-date">3 items · AshLey</span>
|
|
283
|
+
</div>
|
|
284
|
+
<div class="briefing-items">
|
|
285
|
+
<div class="briefing-item">
|
|
286
|
+
<div class="priority-dot" style="background:#ef4444;"></div>
|
|
287
|
+
<div class="briefing-item-text">Investor update deck — Board meeting tomorrow, slides not finalized</div>
|
|
288
|
+
<div class="briefing-actions">
|
|
289
|
+
<button class="baction-btn" onclick="deferItem(this)">Defer →</button>
|
|
290
|
+
<button class="baction-btn" onclick="delegateItem(this)">Delegate →</button>
|
|
291
|
+
<button class="baction-btn decide" onclick="decideItem(this)">Decide ✓</button>
|
|
292
|
+
</div>
|
|
293
|
+
</div>
|
|
294
|
+
<div class="briefing-item">
|
|
295
|
+
<div class="priority-dot" style="background:#f59e0b;"></div>
|
|
296
|
+
<div class="briefing-item-text">Q2 hiring plan — Sarah waiting on headcount sign-off</div>
|
|
297
|
+
<div class="briefing-actions">
|
|
298
|
+
<button class="baction-btn" onclick="deferItem(this)">Defer →</button>
|
|
299
|
+
<button class="baction-btn" onclick="delegateItem(this)">Delegate →</button>
|
|
300
|
+
<button class="baction-btn decide" onclick="decideItem(this)">Decide ✓</button>
|
|
301
|
+
</div>
|
|
302
|
+
</div>
|
|
303
|
+
<div class="briefing-item">
|
|
304
|
+
<div class="priority-dot" style="background:#4ade80;"></div>
|
|
305
|
+
<div class="briefing-item-text">Team offsite logistics — Venue confirmed, agenda draft ready</div>
|
|
306
|
+
<div class="briefing-actions">
|
|
307
|
+
<button class="baction-btn" onclick="deferItem(this)">Defer →</button>
|
|
308
|
+
<button class="baction-btn" onclick="delegateItem(this)">Delegate →</button>
|
|
309
|
+
<button class="baction-btn decide" onclick="decideItem(this)">Decide ✓</button>
|
|
310
|
+
</div>
|
|
311
|
+
</div>
|
|
312
|
+
</div>
|
|
313
|
+
</div>
|
|
314
|
+
|
|
315
|
+
<div class="source-ref">
|
|
316
|
+
📎 Source: <a href="#">Ashley-Calendar-AI · feat/1150-dashboard-improvements · src/components/BriefingCard.tsx</a>
|
|
317
|
+
</div>
|
|
318
|
+
</div>
|
|
319
|
+
</div>
|
|
320
|
+
|
|
321
|
+
<!-- Card 2: Voice-First Scheduling -->
|
|
322
|
+
<div class="card" id="card2">
|
|
323
|
+
<div class="card-header" onclick="toggleCard(2)">
|
|
324
|
+
<div class="card-icon" style="background:#fef3c7;">🎙️</div>
|
|
325
|
+
<div class="card-meta">
|
|
326
|
+
<div class="card-tag" style="color:#f59e0b;">Zero-Tap UX</div>
|
|
327
|
+
<div class="card-title">"Schedule this" → Done in 3 seconds</div>
|
|
328
|
+
<div class="card-subtitle">Ashley-Calendar-AI · feat/1134-voice-mode</div>
|
|
329
|
+
</div>
|
|
330
|
+
<div class="card-toggle">›</div>
|
|
331
|
+
</div>
|
|
332
|
+
<div class="card-body">
|
|
333
|
+
<div class="card-context">A Series-B founder was manually scheduling 6-8 meetings daily, losing 45 minutes per day to calendar logistics.</div>
|
|
334
|
+
|
|
335
|
+
<div class="narrative">
|
|
336
|
+
<div class="narrative-step">
|
|
337
|
+
<div class="step-label">Problem</div>
|
|
338
|
+
<div class="step-text">Every scheduling request followed the same 4-step dance: open calendar, find a free slot, send invite, wait for confirm. For a person whose time is their most constrained resource, this was absurd.</div>
|
|
339
|
+
</div>
|
|
340
|
+
<div class="narrative-step">
|
|
341
|
+
<div class="step-label">What AshLey Did</div>
|
|
342
|
+
<div class="step-text">AshLey implemented voice-intent scheduling. The founder says "Schedule a 30-min check-in with Sarah next week, mornings preferred." AshLey parses the intent, queries both calendars for mutual availability, proposes 3 options ranked by attendee energy levels (morning sharpness score), and sends the invite with one tap.</div>
|
|
343
|
+
</div>
|
|
344
|
+
<div class="narrative-step">
|
|
345
|
+
<div class="step-label">The Outcome</div>
|
|
346
|
+
<div class="step-text">End-to-end scheduling time fell from 4 minutes to under 15 seconds. The founder reported reclaiming 30+ minutes per day across 6 months.</div>
|
|
347
|
+
</div>
|
|
348
|
+
</div>
|
|
349
|
+
|
|
350
|
+
<div class="artifact-label">Live Artifact — Voice Scheduling Interface</div>
|
|
351
|
+
|
|
352
|
+
<div class="voice-card">
|
|
353
|
+
<button class="mic-btn" onclick="startVoice()" id="micBtn">🎙️</button>
|
|
354
|
+
<div class="waveform" id="waveform">
|
|
355
|
+
<div class="wave-bar" style="height:10px;"></div>
|
|
356
|
+
<div class="wave-bar" style="height:20px;"></div>
|
|
357
|
+
<div class="wave-bar" style="height:30px;"></div>
|
|
358
|
+
<div class="wave-bar" style="height:20px;"></div>
|
|
359
|
+
<div class="wave-bar" style="height:10px;"></div>
|
|
360
|
+
</div>
|
|
361
|
+
<div class="voice-status" id="voiceStatus">Tap mic to schedule</div>
|
|
362
|
+
<div class="slot-chips" id="slotChips">
|
|
363
|
+
<div class="slot-chip" onclick="selectSlot(this, 1)">Mon 9am</div>
|
|
364
|
+
<div class="slot-chip" onclick="selectSlot(this, 2)">Tue 8:30am</div>
|
|
365
|
+
<div class="slot-chip" onclick="selectSlot(this, 3)">Wed 10am</div>
|
|
366
|
+
</div>
|
|
367
|
+
<div class="invite-sent" id="inviteSent"></div>
|
|
368
|
+
</div>
|
|
369
|
+
|
|
370
|
+
<div class="source-ref">
|
|
371
|
+
📎 Source: <a href="#">Ashley-Calendar-AI · feat/1134-voice-mode · src/hooks/useVoiceScheduler.ts</a>
|
|
372
|
+
</div>
|
|
373
|
+
</div>
|
|
374
|
+
</div>
|
|
375
|
+
|
|
376
|
+
<!-- Card 3: Smart Delegate Detection -->
|
|
377
|
+
<div class="card" id="card3">
|
|
378
|
+
<div class="card-header" onclick="toggleCard(3)">
|
|
379
|
+
<div class="card-icon" style="background:#fef3c7;">🎯</div>
|
|
380
|
+
<div class="card-meta">
|
|
381
|
+
<div class="card-tag" style="color:#f59e0b;">Executive Leverage</div>
|
|
382
|
+
<div class="card-title">"Should I be in this meeting?" auto-answered</div>
|
|
383
|
+
<div class="card-subtitle">Ashley-Calendar-AI · intelligence-layer · src/services/meeting-relevance.ts</div>
|
|
384
|
+
</div>
|
|
385
|
+
<div class="card-toggle">›</div>
|
|
386
|
+
</div>
|
|
387
|
+
<div class="card-body">
|
|
388
|
+
<div class="card-context">A COO was attending 22 meetings per week. Her PA estimated 40% of them didn't require her presence.</div>
|
|
389
|
+
|
|
390
|
+
<div class="narrative">
|
|
391
|
+
<div class="narrative-step">
|
|
392
|
+
<div class="step-label">Problem</div>
|
|
393
|
+
<div class="step-text">Calendar blockers accumulate without review. Recurring meetings auto-renew even when the original reason has resolved. High-urgency events from junior team members land next to board calls without priority discrimination.</div>
|
|
394
|
+
</div>
|
|
395
|
+
<div class="narrative-step">
|
|
396
|
+
<div class="step-label">What AshLey Did</div>
|
|
397
|
+
<div class="step-text">AshLey's meeting-relevance scorer weighs four signals: attendee seniority (does this require her decision authority?), topic recurrence (has this been resolved in a prior meeting?), her stated goals this quarter, and her delegation map. Each calendar event gets a score from 0–100 with a one-line "attend / delegate / skip" recommendation.</div>
|
|
398
|
+
</div>
|
|
399
|
+
<div class="narrative-step">
|
|
400
|
+
<div class="step-label">The Outcome</div>
|
|
401
|
+
<div class="step-text">The COO reduced meeting load by 8 meetings per week in the first month. Her EA repurposed 3 hours weekly from scheduling/rescheduling to strategic prep.</div>
|
|
402
|
+
</div>
|
|
403
|
+
</div>
|
|
404
|
+
|
|
405
|
+
<div class="artifact-label">Live Artifact — Meeting Relevance Dashboard</div>
|
|
406
|
+
|
|
407
|
+
<div class="rel-table-wrap">
|
|
408
|
+
<table class="rel-table">
|
|
409
|
+
<thead>
|
|
410
|
+
<tr>
|
|
411
|
+
<th>Meeting Title</th>
|
|
412
|
+
<th>Score</th>
|
|
413
|
+
<th>Recommendation</th>
|
|
414
|
+
</tr>
|
|
415
|
+
</thead>
|
|
416
|
+
<tbody>
|
|
417
|
+
<tr>
|
|
418
|
+
<td>Weekly all-hands</td>
|
|
419
|
+
<td><span class="score-mono" style="color:#10b981;">82</span></td>
|
|
420
|
+
<td><span class="rec-badge badge-attend">ATTEND</span></td>
|
|
421
|
+
</tr>
|
|
422
|
+
<tr>
|
|
423
|
+
<td>Sprint planning — mobile team</td>
|
|
424
|
+
<td><span class="score-mono" style="color:#f59e0b;">34</span></td>
|
|
425
|
+
<td><span class="rec-badge badge-delegate">DELEGATE</span></td>
|
|
426
|
+
</tr>
|
|
427
|
+
<tr>
|
|
428
|
+
<td>Vendor NDA review</td>
|
|
429
|
+
<td><span class="score-mono" style="color:#94a3b8;">19</span></td>
|
|
430
|
+
<td><span class="rec-badge badge-skip">SKIP</span></td>
|
|
431
|
+
</tr>
|
|
432
|
+
<tr>
|
|
433
|
+
<td>Board prep — Q2 financials</td>
|
|
434
|
+
<td><span class="score-mono" style="color:#10b981;">95</span></td>
|
|
435
|
+
<td><span class="rec-badge badge-attend">ATTEND</span></td>
|
|
436
|
+
</tr>
|
|
437
|
+
<tr>
|
|
438
|
+
<td>Office seating plan</td>
|
|
439
|
+
<td><span class="score-mono" style="color:#94a3b8;">11</span></td>
|
|
440
|
+
<td><span class="rec-badge badge-skip">SKIP</span></td>
|
|
441
|
+
</tr>
|
|
442
|
+
</tbody>
|
|
443
|
+
</table>
|
|
444
|
+
</div>
|
|
445
|
+
|
|
446
|
+
<div class="source-ref">
|
|
447
|
+
📎 Source: <a href="#">Ashley-Calendar-AI · intelligence-layer · src/services/meeting-relevance.ts</a>
|
|
448
|
+
</div>
|
|
449
|
+
</div>
|
|
450
|
+
</div>
|
|
451
|
+
|
|
452
|
+
</div>
|
|
453
|
+
|
|
454
|
+
<footer class="portfolio-footer">
|
|
455
|
+
<div class="footer-sub">
|
|
456
|
+
Part of the <a href="/">FRAIM</a> · 18 AI employees available ·
|
|
457
|
+
<a href="/">View all employees</a>
|
|
458
|
+
</div>
|
|
459
|
+
</footer>
|
|
460
|
+
|
|
461
|
+
<script>
|
|
462
|
+
function toggleTheme() {
|
|
463
|
+
const html = document.documentElement;
|
|
464
|
+
const isDark = html.getAttribute('data-theme') === 'dark';
|
|
465
|
+
html.setAttribute('data-theme', isDark ? 'light' : 'dark');
|
|
466
|
+
document.querySelector('.theme-btn').textContent = isDark ? '☾' : '☀';
|
|
467
|
+
}
|
|
468
|
+
if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
|
|
469
|
+
document.documentElement.setAttribute('data-theme', 'dark');
|
|
470
|
+
document.querySelector('.theme-btn').textContent = '☀';
|
|
471
|
+
}
|
|
472
|
+
function toggleCard(num) {
|
|
473
|
+
const card = document.getElementById('card' + num);
|
|
474
|
+
const isOpen = card.classList.contains('open');
|
|
475
|
+
document.querySelectorAll('.card').forEach(c => c.classList.remove('open'));
|
|
476
|
+
if (!isOpen) { card.classList.add('open'); card.scrollIntoView({ behavior: 'smooth', block: 'nearest' }); }
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
function decideItem(btn) {
|
|
480
|
+
btn.classList.add('decided');
|
|
481
|
+
btn.textContent = '✓ Decided';
|
|
482
|
+
const item = btn.closest('.briefing-item');
|
|
483
|
+
item.style.opacity = '0.5';
|
|
484
|
+
}
|
|
485
|
+
function deferItem(btn) {
|
|
486
|
+
const item = btn.closest('.briefing-item');
|
|
487
|
+
item.style.opacity = '0.4';
|
|
488
|
+
btn.textContent = '⏱ Deferred';
|
|
489
|
+
btn.style.color = '#94a3b8';
|
|
490
|
+
}
|
|
491
|
+
function delegateItem(btn) {
|
|
492
|
+
const item = btn.closest('.briefing-item');
|
|
493
|
+
btn.textContent = '↗ Delegated';
|
|
494
|
+
btn.style.color = '#60a5fa';
|
|
495
|
+
item.style.opacity = '0.45';
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
const voiceStates = ['Listening...', 'Checking Sarah\'s calendar...', '3 options found'];
|
|
499
|
+
let voiceIdx = 0;
|
|
500
|
+
let voiceTimer = null;
|
|
501
|
+
function startVoice() {
|
|
502
|
+
if (voiceTimer) return;
|
|
503
|
+
voiceIdx = 0;
|
|
504
|
+
document.getElementById('voiceStatus').textContent = voiceStates[0];
|
|
505
|
+
voiceTimer = setInterval(() => {
|
|
506
|
+
voiceIdx++;
|
|
507
|
+
if (voiceIdx < voiceStates.length) {
|
|
508
|
+
document.getElementById('voiceStatus').textContent = voiceStates[voiceIdx];
|
|
509
|
+
} else {
|
|
510
|
+
clearInterval(voiceTimer);
|
|
511
|
+
voiceTimer = null;
|
|
512
|
+
}
|
|
513
|
+
}, 1400);
|
|
514
|
+
}
|
|
515
|
+
function selectSlot(el, num) {
|
|
516
|
+
document.querySelectorAll('.slot-chip').forEach(c => c.classList.remove('selected'));
|
|
517
|
+
el.classList.add('selected');
|
|
518
|
+
document.getElementById('inviteSent').textContent = '✓ Invite sent';
|
|
519
|
+
}
|
|
520
|
+
</script>
|
|
521
|
+
|
|
522
|
+
</body>
|
|
523
|
+
</html>
|
|
@@ -0,0 +1,83 @@
|
|
|
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>AUDITya - AI Banking Auditor - 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@400;500;600;700;800&family=JetBrains+Mono:wght@500;700&display=swap" rel="stylesheet">
|
|
10
|
+
<style>
|
|
11
|
+
:root { --accent:#7c3aed; --accent-2:#0f172a; --text:#111827; --muted:#64748b; --bg:#f8fafc; --surface:#fff; --surface-2:#f3f0ff; --border:#ddd6fe; --shadow:0 12px 36px rgba(17,24,39,.12); }
|
|
12
|
+
[data-theme="dark"] { --text:#f8fafc; --muted:#94a3b8; --bg:#090b14; --surface:#111827; --surface-2:#1f1b35; --border:#3b2d66; --shadow:0 12px 36px rgba(0,0,0,.42); }
|
|
13
|
+
* { box-sizing:border-box; margin:0; padding:0; }
|
|
14
|
+
body { font-family:Inter,sans-serif; background:var(--bg); color:var(--text); min-height:100vh; }
|
|
15
|
+
.site-header { position:sticky; top:0; z-index:10; display:flex; justify-content:space-between; align-items:center; padding:14px 32px; background:var(--surface); border-bottom:1px solid var(--border); }
|
|
16
|
+
.brand { display:flex; align-items:center; gap:10px; color:var(--text); text-decoration:none; font-weight:800; }
|
|
17
|
+
.brand-logo { width:32px; height:32px; border-radius:8px; display:grid; place-items:center; color:#fff; background:linear-gradient(135deg,var(--accent),var(--accent-2)); }
|
|
18
|
+
.theme-btn { background:var(--surface-2); color:var(--muted); border:1px solid var(--border); border-radius:8px; padding:7px 10px; cursor:pointer; }
|
|
19
|
+
.hero { max-width:960px; margin:56px auto 0; padding:0 24px; text-align:center; }
|
|
20
|
+
.avatar { width:96px; height:96px; margin:0 auto 22px; border-radius:50%; display:grid; place-items:center; color:#fff; font:800 38px/1 JetBrains Mono,monospace; background:linear-gradient(135deg,var(--accent),var(--accent-2)); box-shadow:0 0 0 8px var(--surface-2); }
|
|
21
|
+
.chip { display:inline-block; color:var(--accent); background:var(--surface-2); border:1px solid var(--border); border-radius:999px; padding:5px 14px; font-size:12px; font-weight:800; letter-spacing:.04em; text-transform:uppercase; }
|
|
22
|
+
h1 { margin:18px auto 14px; font-size:clamp(34px,5vw,56px); line-height:1.05; letter-spacing:-1px; max-width:780px; }
|
|
23
|
+
h1 span { color:var(--accent); }
|
|
24
|
+
.hero p { color:var(--muted); font-size:17px; line-height:1.7; max-width:700px; margin:0 auto; }
|
|
25
|
+
.section { max-width:980px; margin:56px auto 80px; padding:0 24px; display:grid; gap:18px; }
|
|
26
|
+
.card { background:var(--surface); border:1px solid var(--border); border-radius:14px; box-shadow:var(--shadow); overflow:hidden; }
|
|
27
|
+
.card-head { padding:22px 24px; display:flex; gap:16px; align-items:flex-start; cursor:pointer; }
|
|
28
|
+
.num { width:40px; height:40px; border-radius:10px; display:grid; place-items:center; color:#fff; background:linear-gradient(135deg,var(--accent),var(--accent-2)); font-weight:800; }
|
|
29
|
+
.meta { flex:1; min-width:0; }
|
|
30
|
+
.tag { color:var(--accent); font-size:11px; font-weight:800; letter-spacing:.08em; text-transform:uppercase; margin-bottom:6px; }
|
|
31
|
+
.title { font-size:19px; font-weight:800; margin-bottom:5px; }
|
|
32
|
+
.sub { color:var(--muted); font-size:13px; line-height:1.5; }
|
|
33
|
+
.body { display:none; border-top:1px solid var(--border); padding:24px; }
|
|
34
|
+
.card.open .body { display:block; }
|
|
35
|
+
.grid { display:grid; grid-template-columns:repeat(3,1fr); gap:14px; margin-bottom:20px; }
|
|
36
|
+
.box { background:var(--surface-2); border-radius:10px; padding:14px; }
|
|
37
|
+
.box b { display:block; color:var(--accent); font-size:11px; letter-spacing:.08em; text-transform:uppercase; margin-bottom:6px; }
|
|
38
|
+
.box span { color:var(--muted); font-size:13px; line-height:1.55; }
|
|
39
|
+
table { width:100%; border-collapse:collapse; background:var(--surface-2); border-radius:10px; overflow:hidden; }
|
|
40
|
+
th,td { text-align:left; padding:11px 12px; border-bottom:1px solid var(--border); font-size:12px; vertical-align:top; }
|
|
41
|
+
th { color:var(--accent); font-size:11px; text-transform:uppercase; letter-spacing:.06em; }
|
|
42
|
+
.mono { font-family:JetBrains Mono,monospace; font-size:12px; }
|
|
43
|
+
@media (max-width:720px) { .site-header { padding:12px 16px; } .grid { grid-template-columns:1fr; } }
|
|
44
|
+
</style>
|
|
45
|
+
</head>
|
|
46
|
+
<body>
|
|
47
|
+
<header class="site-header">
|
|
48
|
+
<a class="brand" href="/portfolio/"><div class="brand-logo">F</div><span>FRAIM</span></a>
|
|
49
|
+
<button class="theme-btn" onclick="toggleTheme()" title="Toggle dark mode">Theme</button>
|
|
50
|
+
</header>
|
|
51
|
+
<section class="hero">
|
|
52
|
+
<div class="avatar"><img src="https://api.dicebear.com/9.x/notionists/svg?seed=AUDITya-banking-audit&backgroundColor=e9d5ff&radius=50" width="96" height="96" alt="AUDITya banking auditor avatar" style="border-radius:50%;"></div>
|
|
53
|
+
<div class="chip">AI Banking Auditor</div>
|
|
54
|
+
<h1>AUDITya reviews AI banking work with <span>evidence discipline</span>.</h1>
|
|
55
|
+
<p>AUDITya audits a completed KYC run, checks whether the decision is supported by evidence, records exceptions, and produces a report that can be revisited in a future review.</p>
|
|
56
|
+
</section>
|
|
57
|
+
<main class="section">
|
|
58
|
+
<article class="card open">
|
|
59
|
+
<div class="card-head" onclick="toggleCard(this)"><div class="num">1</div><div class="meta"><div class="tag">Banking audit</div><div class="title">Control-by-control evidence review</div><div class="sub">Maps KYC requirements to artifact paths and evidence ids.</div></div></div>
|
|
60
|
+
<div class="body">
|
|
61
|
+
<div class="grid"><div class="box"><b>Problem</b><span>A banking team needs to inspect an AI KYC decision after the fact.</span></div><div class="box"><b>Work</b><span>AUDITya reads the KYC bundle, decision, and receipt without modifying the original source package.</span></div><div class="box"><b>Outcome</b><span>The audit concludes pass with observations and leaves an audit receipt for future review.</span></div></div>
|
|
62
|
+
<table><tr><th>Control</th><th>Evidence</th><th>Status</th><th>Finding</th></tr><tr><td>Consent scope</td><td class="mono">kyc-e-001</td><td>Satisfied</td><td>Purpose and expiry match the KYC review.</td></tr><tr><td>Decision trace</td><td class="mono">docs/banking/{case-id}/{case-id}-{date}-kyc-review.docx</td><td>Satisfied</td><td>Decision reasons cite evidence ids.</td></tr><tr><td>Velocity risk</td><td class="mono">kyc-e-006</td><td>Observation</td><td>Source mode is disclosed and not reliance-blocking when accepted by policy.</td></tr></table>
|
|
63
|
+
</div>
|
|
64
|
+
</article>
|
|
65
|
+
<article class="card">
|
|
66
|
+
<div class="card-head" onclick="toggleCard(this)"><div class="num">2</div><div class="meta"><div class="tag">Exceptions</div><div class="title">Visible gaps instead of hidden assumptions</div><div class="sub">Unavailable or weak evidence remains in the audit trail.</div></div></div>
|
|
67
|
+
<div class="body">
|
|
68
|
+
<table><tr><th>Exception id</th><th>Severity</th><th>Finding</th><th>Reliance impact</th></tr><tr><td class="mono">aud-ex-001</td><td>Observation</td><td>Velocity signal is marked sandbox or provided rather than live.</td><td>Acceptable when disclosed; blocks production reliance if a live source is required.</td></tr><tr><td class="mono">aud-ex-002</td><td>Observation</td><td>Sanctions check lacks vendor attestation.</td><td>Document source provenance or route to manual review.</td></tr></table>
|
|
69
|
+
</div>
|
|
70
|
+
</article>
|
|
71
|
+
<article class="card">
|
|
72
|
+
<div class="card-head" onclick="toggleCard(this)"><div class="num">3</div><div class="meta"><div class="tag">Audit decision</div><div class="title">Reusable audit report and receipt</div><div class="sub">The audit package points back to the exact KYC artifacts reviewed.</div></div></div>
|
|
73
|
+
<div class="body">
|
|
74
|
+
<table><tr><th>Artifact</th><th>Purpose</th></tr><tr><td class="mono">docs/banking/{case-id}/{case-id}-{date}-audit-report.docx</td><td>Readable source inventory, control review, exceptions, audit decision, and receipt.</td></tr><tr><td class="mono">docs/banking/{case-id}/{case-id}-{date}-kyc-review.docx</td><td>Source KYC review artifact reviewed by the auditor.</td></tr></table>
|
|
75
|
+
</div>
|
|
76
|
+
</article>
|
|
77
|
+
</main>
|
|
78
|
+
<script>
|
|
79
|
+
function toggleTheme(){const html=document.documentElement;html.setAttribute('data-theme',html.getAttribute('data-theme')==='dark'?'light':'dark');}
|
|
80
|
+
function toggleCard(header){header.closest('.card').classList.toggle('open');}
|
|
81
|
+
</script>
|
|
82
|
+
</body>
|
|
83
|
+
</html>
|