launcher: align EDUT ID naming across UI and docs
Some checks are pending
check / launcher (push) Waiting to run

This commit is contained in:
Edut LLC 2026-02-20 15:50:53 -08:00
parent 33283b95d6
commit ce42646931
7 changed files with 39 additions and 37 deletions

View File

@ -72,7 +72,7 @@ Policy behavior in launcher shell:
Run locally:
```bash
cd <home>/Documents/VSG\ Codex/launcher/app
cd <workspace-root>/launcher/app
python3 -m http.server 4310
```

View File

@ -297,13 +297,13 @@ function setButtonDisabled(id, disabled) {
function refreshActionLocks(statusPayload) {
const effective = statusPayload && typeof statusPayload === "object" ? statusPayload : state.lastStatus;
const membershipActive = String(effective?.status || "").toLowerCase() === "active";
const edutIdActive = String(effective?.status || "").toLowerCase() === "active";
const attested = isOnrampAttested(effective?.identity_assurance_level);
const ownerActionReady = membershipActive && attested;
const ownerActionReady = edutIdActive && attested;
setButtonDisabled("btnSupportTicket", !ownerActionReady);
setButtonDisabled("btnInstallToken", !ownerActionReady);
setButtonDisabled("btnQuickInstallStatus", !membershipActive);
setButtonDisabled("btnQuickInstallStatus", !edutIdActive);
}
function refreshOverview(statusPayload) {
@ -313,7 +313,7 @@ function refreshOverview(statusPayload) {
setSummary("summarySession", sessionSummary());
refreshModeUI();
if (statusPayload && typeof statusPayload === "object") {
setSummary("summaryMembership", statusPayload.status || "unknown");
setSummary("summaryEdutId", statusPayload.status || "unknown");
setSummary("summaryDesignation", statusPayload.designation_code || "-");
const assurance = assuranceDisplay(statusPayload.identity_assurance_level);
setSummary("summaryAssurance", assurance);
@ -679,7 +679,7 @@ async function onSignPayerProof() {
});
}
async function onSendMembershipTx() {
async function onSendEdutIdTx() {
if (!state.lastQuote || !state.lastQuote.tx) {
throw new Error("request quote before sending transaction");
}
@ -815,7 +815,7 @@ async function onQuote() {
return out;
}
async function onConfirmMembership() {
async function onConfirmEdutId() {
const payload = {
designation_code: $("designationCode").value.trim(),
quote_id: $("quoteId").value.trim(),
@ -823,9 +823,9 @@ async function onConfirmMembership() {
address: requireWallet(),
chain_id: chainID(),
};
const assurance = $("membershipIdentityAssurance").value.trim();
const attestedBy = $("membershipIdentityAttestedBy").value.trim();
const attestationID = $("membershipIdentityAttestationId").value.trim();
const assurance = $("edutIdIdentityAssurance").value.trim();
const attestedBy = $("edutIdIdentityAttestedBy").value.trim();
const attestationID = $("edutIdIdentityAttestationId").value.trim();
if (assurance) {
payload.identity_assurance_level = assurance;
}
@ -849,7 +849,7 @@ async function onConfirmMembership() {
return out;
}
async function requireMembershipState(actionLabel, opts = {}) {
async function requireEdutIdState(actionLabel, opts = {}) {
const status = await onStatus();
if (String(status.status || "").toLowerCase() !== "active") {
throw new Error(`${actionLabel} requires active EDUT ID`);
@ -880,11 +880,11 @@ async function waitForTxMined(txHash, timeoutMs = 120000, intervalMs = 3000) {
throw new Error(`transaction not mined within ${timeoutMs}ms`);
}
async function confirmMembershipWithRetry(maxAttempts = 8, intervalMs = 2500) {
async function confirmEdutIdWithRetry(maxAttempts = 8, intervalMs = 2500) {
let lastErr = null;
for (let attempt = 1; attempt <= maxAttempts; attempt += 1) {
try {
const out = await onConfirmMembership();
const out = await onConfirmEdutId();
return out;
} catch (err) {
lastErr = err;
@ -899,7 +899,7 @@ async function confirmMembershipWithRetry(maxAttempts = 8, intervalMs = 2500) {
throw lastErr || new Error("EDUT ID confirmation failed");
}
async function onRunMembershipFlow() {
async function onRunEdutIdFlow() {
setFlowStatus("connecting wallet");
await onConnectWallet();
@ -919,7 +919,7 @@ async function onRunMembershipFlow() {
setFlowStatus("quoting EDUT ID");
await onQuote();
setFlowStatus("sending EDUT ID transaction");
await onSendMembershipTx();
await onSendEdutIdTx();
const txHash = $("confirmTxHash").value.trim();
if (!txHash) {
@ -928,7 +928,7 @@ async function onRunMembershipFlow() {
setFlowStatus("waiting for chain confirmation");
await waitForTxMined(txHash);
setFlowStatus("confirming EDUT ID with API");
await confirmMembershipWithRetry();
await confirmEdutIdWithRetry();
setFlowStatus("refreshing status");
const refreshed = await onStatus();
if (isOnrampAttested(refreshed.identity_assurance_level)) {
@ -986,7 +986,7 @@ async function onPollEvents() {
}
async function onSupportTicket() {
await requireMembershipState("owner support", { requireOnramp: true });
await requireEdutIdState("owner support", { requireOnramp: true });
const out = await request("POST", "/member/channel/support/ticket", {
wallet: requireWallet(),
org_root_id: orgRootID(),
@ -1002,7 +1002,7 @@ async function onSupportTicket() {
}
async function onInstallToken() {
await requireMembershipState("governance install token", { requireOnramp: true });
await requireEdutIdState("governance install token", { requireOnramp: true });
const out = await request("POST", "/governance/install/token", {
wallet: requireWallet(),
org_root_id: orgRootID(),
@ -1136,7 +1136,9 @@ async function confirmCheckoutWithRetry(maxAttempts = 8, intervalMs = 2500) {
} catch (err) {
lastErr = err;
const message = String(err || "");
if (!message.includes("tx verification pending/failed") && !message.includes("membership verification pending/failed")) {
if (!message.includes("tx verification pending/failed")
&& !message.includes("edut id verification pending/failed")
&& !message.includes("membership verification pending/failed")) {
throw err;
}
setFlowStatus(`checkout confirm pending (${attempt}/${maxAttempts})`);
@ -1188,7 +1190,7 @@ async function onQuickConnect() {
}
async function onQuickActivate() {
await onRunMembershipFlow();
await onRunEdutIdFlow();
try {
await ensureChannelBinding();
await onPollEvents();
@ -1283,7 +1285,7 @@ bind("btnCopyWallet", onCopyWallet);
bind("btnModeHuman", onModeHuman);
bind("btnModeAuto", onModeAuto);
bind("btnConnectWallet", onConnectWallet);
bind("btnRunMembershipFlow", onRunMembershipFlow);
bind("btnRunEdutIdFlow", onRunEdutIdFlow);
bind("btnIntent", onIntent);
bind("btnSignIntent", onSignIntent);
bind("btnVerify", onVerify);
@ -1292,8 +1294,8 @@ bind("btnRevokeSession", onRevokeSession);
bind("btnStatus", onStatus);
bind("btnQuote", onQuote);
bind("btnSignPayerProof", onSignPayerProof);
bind("btnSendMembershipTx", onSendMembershipTx);
bind("btnConfirmMembership", onConfirmMembership);
bind("btnSendEdutIdTx", onSendEdutIdTx);
bind("btnConfirmEdutId", onConfirmEdutId);
bind("btnRegisterChannel", onRegisterChannel);
bind("btnUnregisterChannel", onUnregisterChannel);
bind("btnPollEvents", onPollEvents);

View File

@ -41,7 +41,7 @@
</article>
<article class="stat">
<h3><span class="term-inline">EDUT ID<details class="inline-help"><summary aria-label="What is EDUT ID?">?</summary><p>EDUT ID is your one-time identity credential used for checkout, activation, and ownership proof.</p></details></span></h3>
<p id="summaryMembership">unknown</p>
<p id="summaryEdutId">unknown</p>
</article>
<article class="stat">
<h3>Mode</h3>
@ -112,7 +112,7 @@
<section class="subpanel">
<h2>EDUT ID Flow Controls</h2>
<div class="actions">
<button id="btnRunMembershipFlow">Run EDUT ID flow</button>
<button id="btnRunEdutIdFlow">Run EDUT ID flow</button>
<button id="btnConnectWallet">Connect wallet</button>
<button id="btnIntent">Create intent</button>
<button id="btnSignIntent">Sign intent (EIP-712)</button>
@ -160,8 +160,8 @@
<div class="actions">
<button id="btnQuote">Get quote</button>
<button id="btnSignPayerProof">Sign payer proof</button>
<button id="btnSendMembershipTx">Send EDUT ID tx</button>
<button id="btnConfirmMembership">Confirm EDUT ID tx</button>
<button id="btnSendEdutIdTx">Send EDUT ID tx</button>
<button id="btnConfirmEdutId">Confirm EDUT ID tx</button>
</div>
<div class="grid three">
<label>
@ -198,7 +198,7 @@
<div class="grid three">
<label>
Identity assurance (optional)
<select id="membershipIdentityAssurance">
<select id="edutIdIdentityAssurance">
<option value="">(auto)</option>
<option value="onramp_attested">onramp_attested</option>
<option value="crypto_direct_unattested">crypto_direct_unattested</option>
@ -207,11 +207,11 @@
</label>
<label>
Attested by (optional)
<input id="membershipIdentityAttestedBy" placeholder="moonpay" />
<input id="edutIdIdentityAttestedBy" placeholder="moonpay" />
</label>
<label>
Attestation id (optional)
<input id="membershipIdentityAttestationId" placeholder="provider-session-id" />
<input id="edutIdIdentityAttestationId" placeholder="provider-session-id" />
</label>
</div>
</section>

View File

@ -5,7 +5,7 @@
"channel": "stable",
"features": {
"wallet_bootstrap": true,
"membership_status": true,
"edut_id_status": true,
"governance_install": true,
"store_preview": false
}

View File

@ -1,7 +1,7 @@
# Launcher Conformance Vectors
1. `L-001` Wallet create keeps private key local and non-exported by default.
2. `L-002` Membership status unknown defaults to blocked checkout/install actions.
2. `L-002` EDUT ID status unknown defaults to blocked checkout/install actions.
3. `L-003` Governance package hash mismatch blocks install.
4. `L-004` Governance package signature mismatch blocks install.
5. `L-005` Expired install token blocks install.
@ -10,6 +10,6 @@
8. `L-008` Wallet onboarding creates local wallet without forcing seed phrase display.
9. `L-009` Outgoing sends require biometric/PIN confirmation.
10. `L-010` Primary wallet screens render USD-first balances and plain-language history.
11. `L-011` Launcher must surface `identity_assurance_level` separately from membership state.
11. `L-011` Launcher must surface `identity_assurance_level` separately from EDUT ID state.
12. `L-012` Owner support and governance install actions are blocked when assurance is not `onramp_attested`.
13. `L-013` Launcher emits signing authority class in governance activation evidence and defaults owner-driven activation to `identity_human`.

View File

@ -14,10 +14,10 @@ Create or import an ownership wallet locally before paid actions.
2. Choose create wallet or import wallet.
3. Keys are generated/stored locally (device trust store/secure hardware where available).
4. Recovery options are shown and confirmed by user.
5. Wallet address becomes ownership identity for memberships and licenses.
5. Wallet address becomes ownership identity for EDUT ID and licenses.
## Rules
1. Launcher never exports private key to EDUT backend.
2. Membership/license ownership binds to ownership wallet.
2. EDUT ID/license ownership binds to ownership wallet.
3. Payment wallet may differ at quote/checkout.

View File

@ -90,7 +90,7 @@ Never show crypto jargon by default.
1. No hidden split charges.
2. User always sees final USD amount before confirmation.
3. Membership and entitlement purchases write deterministic receipts.
3. EDUT ID and entitlement purchases write deterministic receipts.
## 5) Pay Someone
@ -110,7 +110,7 @@ History is plain-language first.
Examples:
1. `Added $100`
2. `Bought Human Membership`
2. `Activated EDUT ID`
3. `Sent $50 to 0x12ab...90ef`
4. `Received $200 from 0x98cd...11aa`