Align web repo to app-channel member communication
This commit is contained in:
parent
d58c92ad55
commit
2e8348826f
@ -7,6 +7,9 @@ Public-facing EDUT web surfaces and deployment specs.
|
||||
```text
|
||||
public/
|
||||
index.html
|
||||
downloads/desktop/index.html
|
||||
downloads/ios/index.html
|
||||
downloads/android/index.html
|
||||
store/index.html
|
||||
store/offers.json
|
||||
trust/index.html
|
||||
@ -45,6 +48,7 @@ docs/
|
||||
migration-policy-v1-to-v2.md
|
||||
issuer-onboarding-pack.md
|
||||
release-gate.md
|
||||
app-channel-spec.md
|
||||
review-notes.md
|
||||
platform-spec-alignment-review.md
|
||||
contracts/
|
||||
|
||||
43
docs/app-channel-spec.md
Normal file
43
docs/app-channel-spec.md
Normal file
@ -0,0 +1,43 @@
|
||||
# App Channel Communication Spec
|
||||
|
||||
## Principle
|
||||
|
||||
Member communication is delivered through EDUT app channels after wallet sign-in.
|
||||
|
||||
## Why
|
||||
|
||||
1. Avoids email deliverability and spam filtering constraints.
|
||||
2. Avoids SMS compliance overhead.
|
||||
3. Keeps communication tied to wallet-authenticated entitlements.
|
||||
|
||||
## Channel Model
|
||||
|
||||
1. Membership mint unlocks app download.
|
||||
2. App sign-in with wallet activates member channel.
|
||||
3. Push/in-app notifications are scoped to member ownership state.
|
||||
4. Web never becomes a long-term broadcast channel once membership is active.
|
||||
|
||||
## Notification Classes
|
||||
|
||||
1. Offer availability relevant to owned memberships/entitlements.
|
||||
2. License activation and entitlement state updates.
|
||||
3. Platform updates and required migration actions.
|
||||
4. Publisher updates for offers a member owns.
|
||||
5. Membership policy changes that affect purchase or activation behavior.
|
||||
|
||||
## Gate Rule
|
||||
|
||||
No active membership -> no app access channel.
|
||||
|
||||
## Deterministic Delivery Rules
|
||||
|
||||
1. Notification eligibility is computed from wallet-authenticated entitlement state.
|
||||
2. Delivery payloads must include deterministic event ids for dedupe and audit.
|
||||
3. Membership revocation/suspension immediately suppresses member-channel delivery.
|
||||
4. No marketing list fan-out disconnected from entitlement state.
|
||||
|
||||
## Non-Goals
|
||||
|
||||
1. Marketing blast lists detached from wallet state.
|
||||
2. SMS-first member notification flows.
|
||||
3. Email-first member notification dependency.
|
||||
@ -8,7 +8,7 @@
|
||||
|
||||
## Backend Responsibilities
|
||||
|
||||
1. Intent/verify/quote/confirm/notify endpoints.
|
||||
1. Intent/verify/quote/confirm/status endpoints.
|
||||
2. Deterministic state transitions and persistence.
|
||||
3. Chain verification and policy hash enforcement.
|
||||
|
||||
|
||||
@ -7,7 +7,7 @@ This matrix prevents drift between public surfaces and legal posture.
|
||||
| Landing (`public/index.html`) | Wallet signature + paid membership unlocks access | Investment, yield, appreciation claims |
|
||||
| Store (`public/store/index.html`) | Membership required for purchasing offers | "Membership includes all products forever" |
|
||||
| Terms (`public/terms/index.html`) | Membership is utility access; licenses separate | Equity/ownership implications |
|
||||
| Privacy (`public/privacy/index.html`) | Wallet/signature processing and optional notify email | Hidden collection claims inconsistent with implementation |
|
||||
| Privacy (`public/privacy/index.html`) | Wallet/signature processing and app-channel member communication model | Hidden collection claims inconsistent with implementation |
|
||||
| Vision/spec docs | Deterministic governance and fail-closed controls | Speculative financial framing |
|
||||
|
||||
## Hard Rules
|
||||
|
||||
@ -24,7 +24,7 @@ Validate membership-flow strings and legal-critical labels across all locale bun
|
||||
1. core identity support keys (`definition`, `descriptor`, `acknowledged`, `privacy`, `terms`)
|
||||
2. wallet flow keys (`continue_label`, `wallet_intro`, `wallet_connecting`, `wallet_signing`, `wallet_verifying`, `wallet_failed`)
|
||||
3. membership flow keys (`membership_quoting`, `membership_minting`, `membership_confirming`, `membership_active`)
|
||||
4. notify keys (`notify_me`, `notify_placeholder`, `notify_submit`, `notify_saved`, `notify_failed`)
|
||||
4. delivery keys (`download_heading`, `download_desktop`, `download_ios`, `download_android`, `app_notifications_note`)
|
||||
|
||||
## QA Checks
|
||||
|
||||
|
||||
@ -28,7 +28,7 @@ The revised web copy is aligned with core platform direction on:
|
||||
- Revised copy avoids hard claims that can conflict with evolving licensing rails.
|
||||
|
||||
3. Secret system spec correctness fixed.
|
||||
- Mailgun signing verification now references signing key.
|
||||
- Legacy email/SMS designation path removed from active flow.
|
||||
- Failure handling now avoids silent acceptance on processing failure.
|
||||
|
||||
## Deliberate Neutrality Choices
|
||||
|
||||
@ -19,7 +19,7 @@
|
||||
|
||||
## API Controls
|
||||
|
||||
1. Rate limits on intent, verify, quote, confirm, notify.
|
||||
1. Rate limits on intent, verify, quote, confirm, and status.
|
||||
2. Request size limits.
|
||||
3. Structured error responses without sensitive internals.
|
||||
4. Correlation ID logging for all transitions.
|
||||
|
||||
54
public/downloads/android/index.html
Normal file
54
public/downloads/android/index.html
Normal file
@ -0,0 +1,54 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>EDUT Platform - Android</title>
|
||||
<meta name="description" content="EDUT Android platform delivery channel.">
|
||||
<style>
|
||||
body {
|
||||
font-family: 'IBM Plex Mono', 'Courier New', Courier, monospace;
|
||||
background: #f0f4f8;
|
||||
color: #2c2c2c;
|
||||
padding: 40px 20px;
|
||||
margin: 0;
|
||||
}
|
||||
.container {
|
||||
max-width: 760px;
|
||||
margin: 0 auto;
|
||||
line-height: 1.7;
|
||||
letter-spacing: 0.06em;
|
||||
font-size: 12px;
|
||||
}
|
||||
h1 {
|
||||
font-size: 18px;
|
||||
font-weight: 300;
|
||||
letter-spacing: 0.12em;
|
||||
text-transform: uppercase;
|
||||
margin: 10px 0 20px;
|
||||
}
|
||||
.muted {
|
||||
color: #5f646b;
|
||||
}
|
||||
.card {
|
||||
margin-top: 18px;
|
||||
padding: 16px;
|
||||
border: 1px solid #d6dce4;
|
||||
background: #f7fafc;
|
||||
}
|
||||
a { color: #2c2c2c; text-decoration: underline; text-underline-offset: 2px; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<p><a href="/">back</a></p>
|
||||
<h1>EDUT Platform Android</h1>
|
||||
<p class="muted">membership channel acknowledged</p>
|
||||
<div class="card">
|
||||
<p>This endpoint is bound to wallet-authenticated membership access.</p>
|
||||
<p>When Android distribution is staged for your designation era, this channel delivers current install instructions.</p>
|
||||
<p>Member updates and entitlement notices are delivered inside the EDUT app after wallet sign-in.</p>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
54
public/downloads/desktop/index.html
Normal file
54
public/downloads/desktop/index.html
Normal file
@ -0,0 +1,54 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>EDUT Platform - Desktop</title>
|
||||
<meta name="description" content="EDUT desktop platform delivery channel.">
|
||||
<style>
|
||||
body {
|
||||
font-family: 'IBM Plex Mono', 'Courier New', Courier, monospace;
|
||||
background: #f0f4f8;
|
||||
color: #2c2c2c;
|
||||
padding: 40px 20px;
|
||||
margin: 0;
|
||||
}
|
||||
.container {
|
||||
max-width: 760px;
|
||||
margin: 0 auto;
|
||||
line-height: 1.7;
|
||||
letter-spacing: 0.06em;
|
||||
font-size: 12px;
|
||||
}
|
||||
h1 {
|
||||
font-size: 18px;
|
||||
font-weight: 300;
|
||||
letter-spacing: 0.12em;
|
||||
text-transform: uppercase;
|
||||
margin: 10px 0 20px;
|
||||
}
|
||||
.muted {
|
||||
color: #5f646b;
|
||||
}
|
||||
.card {
|
||||
margin-top: 18px;
|
||||
padding: 16px;
|
||||
border: 1px solid #d6dce4;
|
||||
background: #f7fafc;
|
||||
}
|
||||
a { color: #2c2c2c; text-decoration: underline; text-underline-offset: 2px; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<p><a href="/">back</a></p>
|
||||
<h1>EDUT Platform Desktop</h1>
|
||||
<p class="muted">membership channel acknowledged</p>
|
||||
<div class="card">
|
||||
<p>This endpoint is bound to wallet-authenticated membership access.</p>
|
||||
<p>When desktop installers are staged for your designation era, this channel delivers them directly.</p>
|
||||
<p>Member updates and entitlement notices are delivered inside the EDUT app after wallet sign-in.</p>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
54
public/downloads/ios/index.html
Normal file
54
public/downloads/ios/index.html
Normal file
@ -0,0 +1,54 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>EDUT Platform - iOS</title>
|
||||
<meta name="description" content="EDUT iOS platform delivery channel.">
|
||||
<style>
|
||||
body {
|
||||
font-family: 'IBM Plex Mono', 'Courier New', Courier, monospace;
|
||||
background: #f0f4f8;
|
||||
color: #2c2c2c;
|
||||
padding: 40px 20px;
|
||||
margin: 0;
|
||||
}
|
||||
.container {
|
||||
max-width: 760px;
|
||||
margin: 0 auto;
|
||||
line-height: 1.7;
|
||||
letter-spacing: 0.06em;
|
||||
font-size: 12px;
|
||||
}
|
||||
h1 {
|
||||
font-size: 18px;
|
||||
font-weight: 300;
|
||||
letter-spacing: 0.12em;
|
||||
text-transform: uppercase;
|
||||
margin: 10px 0 20px;
|
||||
}
|
||||
.muted {
|
||||
color: #5f646b;
|
||||
}
|
||||
.card {
|
||||
margin-top: 18px;
|
||||
padding: 16px;
|
||||
border: 1px solid #d6dce4;
|
||||
background: #f7fafc;
|
||||
}
|
||||
a { color: #2c2c2c; text-decoration: underline; text-underline-offset: 2px; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<p><a href="/">back</a></p>
|
||||
<h1>EDUT Platform iOS</h1>
|
||||
<p class="muted">membership channel acknowledged</p>
|
||||
<div class="card">
|
||||
<p>This endpoint is bound to wallet-authenticated membership access.</p>
|
||||
<p>When iOS distribution is staged for your designation era, this channel delivers current install instructions.</p>
|
||||
<p>Member updates and entitlement notices are delivered inside the EDUT app after wallet sign-in.</p>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@ -251,7 +251,7 @@
|
||||
color: #7a3a3a;
|
||||
}
|
||||
|
||||
.notify-panel {
|
||||
.delivery-panel {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
@ -259,7 +259,7 @@
|
||||
opacity: 0;
|
||||
transition: opacity 500ms ease;
|
||||
}
|
||||
.notify-panel.visible {
|
||||
.delivery-panel.visible {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
@ -415,7 +415,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div id="flow-status" class="flow-status flow-hidden" aria-live="polite"></div>
|
||||
<div id="delivery-panel" class="notify-panel flow-hidden">
|
||||
<div id="delivery-panel" class="delivery-panel flow-hidden">
|
||||
<p class="flow-line localizable" data-i18n="download_heading">download your platform</p>
|
||||
<div class="download-links">
|
||||
<a id="download-desktop" class="flow-link localizable" data-i18n="download_desktop" href="/downloads/desktop">desktop</a>
|
||||
|
||||
@ -47,11 +47,6 @@
|
||||
"membership_active": "العضوية نشطة. تم تأكيد التعيين.",
|
||||
"wallet_failed": "فشل مسار المحفظة.",
|
||||
"wallet_missing": "لم يتم العثور على محفظة على هذا الجهاز.",
|
||||
"notify_me": "أبلغني",
|
||||
"notify_placeholder": "البريد الإلكتروني",
|
||||
"notify_submit": "حفظ",
|
||||
"notify_saved": "تم حفظ الإشعار.",
|
||||
"notify_failed": "تعذر حفظ تفضيل الإشعار.",
|
||||
"download_heading": "نزّل منصتك",
|
||||
"download_desktop": "سطح المكتب",
|
||||
"download_ios": "iOS",
|
||||
|
||||
@ -47,11 +47,6 @@
|
||||
"membership_active": "Membership aktiv. Designation bestaetigt.",
|
||||
"wallet_failed": "Wallet-Ablauf fehlgeschlagen.",
|
||||
"wallet_missing": "Kein Wallet auf diesem Gerät erkannt.",
|
||||
"notify_me": "benachrichtige mich",
|
||||
"notify_placeholder": "E-Mail",
|
||||
"notify_submit": "speichern",
|
||||
"notify_saved": "Benachrichtigung gespeichert.",
|
||||
"notify_failed": "Benachrichtigungseinstellung konnte nicht gespeichert werden.",
|
||||
"download_heading": "lade deine plattform herunter",
|
||||
"download_desktop": "desktop",
|
||||
"download_ios": "iOS",
|
||||
|
||||
@ -47,11 +47,6 @@
|
||||
"membership_active": "Membership active. Designation acknowledged.",
|
||||
"wallet_failed": "Wallet flow failed.",
|
||||
"wallet_missing": "No wallet detected on this device.",
|
||||
"notify_me": "notify me",
|
||||
"notify_placeholder": "email",
|
||||
"notify_submit": "save",
|
||||
"notify_saved": "Notification saved.",
|
||||
"notify_failed": "Could not save notification preference.",
|
||||
"download_heading": "download your platform",
|
||||
"download_desktop": "desktop",
|
||||
"download_ios": "iOS",
|
||||
|
||||
@ -47,11 +47,6 @@
|
||||
"membership_active": "Membresía activa. Designación reconocida.",
|
||||
"wallet_failed": "Falló el flujo de wallet.",
|
||||
"wallet_missing": "No se detectó wallet en este dispositivo.",
|
||||
"notify_me": "notifícame",
|
||||
"notify_placeholder": "correo",
|
||||
"notify_submit": "guardar",
|
||||
"notify_saved": "Notificación guardada.",
|
||||
"notify_failed": "No se pudo guardar la preferencia de notificación.",
|
||||
"download_heading": "descarga tu plataforma",
|
||||
"download_desktop": "escritorio",
|
||||
"download_ios": "iOS",
|
||||
|
||||
@ -47,11 +47,6 @@
|
||||
"membership_active": "Adhesion active. Designation confirmee.",
|
||||
"wallet_failed": "Le flux wallet a echoue.",
|
||||
"wallet_missing": "Aucun wallet detecte sur cet appareil.",
|
||||
"notify_me": "me notifier",
|
||||
"notify_placeholder": "e-mail",
|
||||
"notify_submit": "enregistrer",
|
||||
"notify_saved": "Notification enregistree.",
|
||||
"notify_failed": "Impossible denregistrer la preference de notification.",
|
||||
"download_heading": "telechargez votre plateforme",
|
||||
"download_desktop": "bureau",
|
||||
"download_ios": "iOS",
|
||||
|
||||
@ -47,11 +47,6 @@
|
||||
"membership_active": "החברות פעילה. הייעוד אושר.",
|
||||
"wallet_failed": "תהליך הארנק נכשל.",
|
||||
"wallet_missing": "לא זוהה ארנק במכשיר זה.",
|
||||
"notify_me": "עדכנו אותי",
|
||||
"notify_placeholder": "אימייל",
|
||||
"notify_submit": "שמור",
|
||||
"notify_saved": "ההתראה נשמרה.",
|
||||
"notify_failed": "לא ניתן לשמור את העדפת ההתראה.",
|
||||
"download_heading": "הורד את הפלטפורמה שלך",
|
||||
"download_desktop": "דסקטופ",
|
||||
"download_ios": "iOS",
|
||||
|
||||
@ -47,11 +47,6 @@
|
||||
"membership_active": "सदस्यता सक्रिय है। नामांकन स्वीकार किया गया।",
|
||||
"wallet_failed": "वॉलेट फ़्लो विफल रहा।",
|
||||
"wallet_missing": "इस डिवाइस पर कोई वॉलेट नहीं मिला।",
|
||||
"notify_me": "मुझे सूचित करें",
|
||||
"notify_placeholder": "ईमेल",
|
||||
"notify_submit": "सहेजें",
|
||||
"notify_saved": "सूचना सहेज ली गई।",
|
||||
"notify_failed": "सूचना वरीयता सहेजी नहीं जा सकी।",
|
||||
"download_heading": "अपना प्लेटफ़ॉर्म डाउनलोड करें",
|
||||
"download_desktop": "डेस्कटॉप",
|
||||
"download_ios": "iOS",
|
||||
|
||||
@ -47,11 +47,6 @@
|
||||
"membership_active": "メンバーシップが有効です。指定が確認されました。",
|
||||
"wallet_failed": "ウォレットフローに失敗しました。",
|
||||
"wallet_missing": "この端末でウォレットが見つかりません。",
|
||||
"notify_me": "通知を受け取る",
|
||||
"notify_placeholder": "メール",
|
||||
"notify_submit": "保存",
|
||||
"notify_saved": "通知設定を保存しました。",
|
||||
"notify_failed": "通知設定を保存できませんでした。",
|
||||
"download_heading": "プラットフォームをダウンロード",
|
||||
"download_desktop": "デスクトップ",
|
||||
"download_ios": "iOS",
|
||||
|
||||
@ -47,11 +47,6 @@
|
||||
"membership_active": "멤버십이 활성화되었습니다. 지정이 확인되었습니다.",
|
||||
"wallet_failed": "지갑 흐름에 실패했습니다.",
|
||||
"wallet_missing": "이 기기에서 지갑을 찾을 수 없습니다.",
|
||||
"notify_me": "알림 받기",
|
||||
"notify_placeholder": "이메일",
|
||||
"notify_submit": "저장",
|
||||
"notify_saved": "알림 설정이 저장되었습니다.",
|
||||
"notify_failed": "알림 설정을 저장하지 못했습니다.",
|
||||
"download_heading": "플랫폼 다운로드",
|
||||
"download_desktop": "데스크톱",
|
||||
"download_ios": "iOS",
|
||||
|
||||
@ -47,11 +47,6 @@
|
||||
"membership_active": "Associação ativa. Designação confirmada.",
|
||||
"wallet_failed": "Falha no fluxo de wallet.",
|
||||
"wallet_missing": "Nenhuma wallet detectada neste dispositivo.",
|
||||
"notify_me": "me avise",
|
||||
"notify_placeholder": "e-mail",
|
||||
"notify_submit": "salvar",
|
||||
"notify_saved": "Notificação salva.",
|
||||
"notify_failed": "Não foi possível salvar a preferência de notificação.",
|
||||
"download_heading": "baixe sua plataforma",
|
||||
"download_desktop": "desktop",
|
||||
"download_ios": "iOS",
|
||||
|
||||
@ -47,11 +47,6 @@
|
||||
"membership_active": "Членство активно. Назначение подтверждено.",
|
||||
"wallet_failed": "Сбой процесса кошелька.",
|
||||
"wallet_missing": "Кошелек на этом устройстве не обнаружен.",
|
||||
"notify_me": "уведомить меня",
|
||||
"notify_placeholder": "email",
|
||||
"notify_submit": "сохранить",
|
||||
"notify_saved": "Уведомление сохранено.",
|
||||
"notify_failed": "Не удалось сохранить настройки уведомлений.",
|
||||
"download_heading": "скачайте свою платформу",
|
||||
"download_desktop": "десктоп",
|
||||
"download_ios": "iOS",
|
||||
|
||||
@ -47,11 +47,6 @@
|
||||
"membership_active": "会员已激活。指定已确认。",
|
||||
"wallet_failed": "钱包流程失败。",
|
||||
"wallet_missing": "此设备未检测到钱包。",
|
||||
"notify_me": "通知我",
|
||||
"notify_placeholder": "邮箱",
|
||||
"notify_submit": "保存",
|
||||
"notify_saved": "通知已保存。",
|
||||
"notify_failed": "无法保存通知偏好。",
|
||||
"download_heading": "下载你的平台",
|
||||
"download_desktop": "桌面版",
|
||||
"download_ios": "iOS",
|
||||
|
||||
Loading…
Reference in New Issue
Block a user