@seasonkoh/webaz 0.1.15 → 0.1.17

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.
Files changed (36) hide show
  1. package/LICENSE +1 -1
  2. package/NOTICE +58 -0
  3. package/README.md +84 -6
  4. package/dist/layer0-foundation/L0-2-state-machine/engine.js +3 -0
  5. package/dist/layer1-agent/L1-1-mcp-server/server.js +840 -704
  6. package/dist/layer2-business/L2-8-feedback/build-feedback-engine.js +169 -0
  7. package/dist/layer3-trust/L3-1-dispute-engine/dispute-engine.js +16 -0
  8. package/dist/layer4-economics/L4-3-reputation/reputation-engine.js +1 -0
  9. package/dist/mcp.js +7 -3
  10. package/dist/pwa/data/onboarding-cases.js +345 -0
  11. package/dist/pwa/data/onboarding-quiz.js +247 -0
  12. package/dist/pwa/public/app.js +1469 -105
  13. package/dist/pwa/public/i18n.js +282 -2
  14. package/dist/pwa/public/icon-192.png +0 -0
  15. package/dist/pwa/public/icon-512.png +0 -0
  16. package/dist/pwa/public/manifest.json +5 -2
  17. package/dist/pwa/public/openapi.json +1 -1
  18. package/dist/pwa/public/sw.js +1 -1
  19. package/dist/pwa/routes/admin-protocol-params.js +80 -2
  20. package/dist/pwa/routes/admin-reports.js +14 -9
  21. package/dist/pwa/routes/auth-read.js +3 -1
  22. package/dist/pwa/routes/build-feedback.js +67 -0
  23. package/dist/pwa/routes/disputes-write.js +149 -1
  24. package/dist/pwa/routes/governance-auto-deactivate.js +108 -0
  25. package/dist/pwa/routes/governance-onboarding.js +785 -0
  26. package/dist/pwa/routes/leaderboard.js +10 -2
  27. package/dist/pwa/routes/orders-action.js +5 -1
  28. package/dist/pwa/routes/products-meta.js +30 -0
  29. package/dist/pwa/routes/profile-identity.js +1 -1
  30. package/dist/pwa/routes/public-utils.js +44 -0
  31. package/dist/pwa/routes/rewards-apply.js +210 -0
  32. package/dist/pwa/routes/rewards-auto-downgrade.js +65 -0
  33. package/dist/pwa/routes/rewards-escrow-expire.js +48 -0
  34. package/dist/pwa/routes/webauthn.js +1 -1
  35. package/dist/pwa/server.js +590 -79
  36. package/package.json +11 -6
@@ -0,0 +1,247 @@
1
+ /**
2
+ * Governance Onboarding 题库(spec §4.3)
3
+ * task #1093 阶段 2a — 10 多选题 + 5 短答题
4
+ *
5
+ * **Status**: v1 draft(2026-06-02 草稿,user 后期 review 调整)
6
+ *
7
+ * 4 个领域(per spec §4.3):
8
+ * - 元规则识别(违反哪条)
9
+ * - Iron-Rule 边界(哪些 action 必须 Passkey)
10
+ * - 4 种 dispute 结算路径(release_seller / partial_refund / liability_split / refund_buyer)
11
+ * - 反 outlier 机制(信誉惩罚原则)
12
+ *
13
+ * 合格线:80%(`protocol_params.governance_onboarding.quiz_pass_score`,默认 80)
14
+ *
15
+ * 评分逻辑:
16
+ * - 多选题:correct_answer 完全匹配 → 1 score
17
+ * - 短答题:phase A 简化 — text.length ≥ 50 chars 且非纯空白 → 1 score
18
+ * (phase B+ maintainer 人工评,可补充 case_review_text 字段)
19
+ * - 总分 = score_count / total_count(15 题)百分比
20
+ */
21
+ export const ONBOARDING_QUIZ = [
22
+ // ── 多选题 1-10 ────────────────────────────────────────────────
23
+ {
24
+ id: 'mcq-1',
25
+ type: 'multiple_choice',
26
+ domain: 'meta-rules',
27
+ question_zh: 'maintainer 在 review PR 时,看到代码作者是创始人,因此放宽审核标准。这违反哪条元规则?',
28
+ question_en: 'A maintainer relaxes review standards because the PR author is the founder. Which meta-rule does this violate?',
29
+ options: [
30
+ { key: 'A', text_zh: '#4 不撒谎', text_en: '#4 no lies' },
31
+ { key: 'B', text_zh: '#5 不偏袒', text_en: '#5 no favoritism' },
32
+ { key: 'C', text_zh: '#8 最小介入', text_en: '#8 minimal intervention' },
33
+ { key: 'D', text_zh: '#10 参与者即 webazer', text_en: '#10 participants are webazers' },
34
+ ],
35
+ correct_answer: 'B',
36
+ },
37
+ {
38
+ id: 'mcq-2',
39
+ type: 'multiple_choice',
40
+ domain: 'iron-rule',
41
+ question_zh: '下列哪个 action 必须真人 Passkey 签发?(注:提现无金额门槛,任何金额都需 Passkey)',
42
+ question_en: 'Which action must require real-human Passkey signature? (Note: withdrawal has no amount threshold for Passkey)',
43
+ options: [
44
+ { key: 'A', text_zh: '查看自己的订单', text_en: 'View own orders' },
45
+ { key: 'B', text_zh: '卖家上架商品', text_en: 'Seller lists product' },
46
+ { key: 'C', text_zh: '用户提现资金(任何金额)', text_en: 'User withdrawal (any amount)' },
47
+ { key: 'D', text_zh: '评价商品', text_en: 'Rate a product' },
48
+ ],
49
+ correct_answer: 'C',
50
+ },
51
+ {
52
+ id: 'mcq-3',
53
+ type: 'multiple_choice',
54
+ domain: 'dispute-verdict',
55
+ role_filter: 'arbitrator',
56
+ question_zh: '买家下单 100 WAZ 商品。卖家发货延迟 30 天且无任何物流证据。买家提 dispute。最合理 verdict?',
57
+ question_en: 'Buyer ordered 100 WAZ product. Seller delayed shipping 30 days with no logistics evidence. Buyer raises dispute. Most reasonable verdict?',
58
+ options: [
59
+ { key: 'A', text_zh: 'release_seller(放款给卖家)', text_en: 'release_seller (release to seller)' },
60
+ { key: 'B', text_zh: 'refund_buyer(全额退款给买家)', text_en: 'refund_buyer (full refund to buyer)' },
61
+ { key: 'C', text_zh: 'partial_refund(部分退款)', text_en: 'partial_refund (partial refund)' },
62
+ { key: 'D', text_zh: 'liability_split(平摊)', text_en: 'liability_split (split liability)' },
63
+ ],
64
+ correct_answer: 'B',
65
+ },
66
+ {
67
+ id: 'mcq-4',
68
+ type: 'multiple_choice',
69
+ domain: 'outlier',
70
+ question_zh: 'verifier A 投 pass(认定该 claim 为真),多数 verifier 投 fail。后续 maintainer 复核证实事实是 fail(claim 是假的)。verifier A 该:',
71
+ question_en: 'Verifier A voted pass (claim is true); majority voted fail. Later maintainer review confirmed the fact was fail (claim was false). Verifier A should:',
72
+ options: [
73
+ { key: 'A', text_zh: '不处罚(投票自由)', text_en: 'No penalty (voting freedom)' },
74
+ { key: 'B', text_zh: '信誉惩罚(偏离已查实事实,非偏离多数)', text_en: 'Reputation penalty (deviated from confirmed fact, not from majority)' },
75
+ { key: 'C', text_zh: '永久禁言', text_en: 'Permanent ban' },
76
+ { key: 'D', text_zh: '退还 stake 让他重投', text_en: 'Refund stake and re-vote' },
77
+ ],
78
+ correct_answer: 'B',
79
+ },
80
+ {
81
+ id: 'mcq-5',
82
+ type: 'multiple_choice',
83
+ domain: 'iron-rule',
84
+ question_zh: '下列哪个 不属于 Iron-Rule 真人 Passkey 路径(必须真人确认的 action)?',
85
+ question_en: 'Which one is NOT among the Iron-Rule real-human Passkey paths (actions requiring real-human confirmation)?',
86
+ options: [
87
+ { key: 'A', text_zh: 'arbitrator 仲裁判决', text_en: 'Arbitrator verdict' },
88
+ { key: 'B', text_zh: '用户提现资金(任何金额)', text_en: 'User withdrawal (any amount)' },
89
+ { key: 'C', text_zh: '浏览公开商品列表', text_en: 'Browse public product list' },
90
+ { key: 'D', text_zh: '删除自己的 Passkey', text_en: 'Delete own Passkey' },
91
+ ],
92
+ correct_answer: 'C',
93
+ },
94
+ {
95
+ id: 'mcq-6',
96
+ type: 'multiple_choice',
97
+ domain: 'governance',
98
+ question_zh: 'framework §3.1 / §3.2 说:二叉树位置是…',
99
+ question_en: 'framework §3.1 / §3.2 says: binary-tree position is...',
100
+ options: [
101
+ { key: 'A', text_zh: '独立收益源(占位就有钱)', text_en: 'Independent income source (hold = earn)' },
102
+ { key: 'B', text_zh: '关系层记录 + 估值层修饰参数(base 必须 > 0)', text_en: 'Relationship-layer record + valuation-layer modifier (base must be > 0)' },
103
+ { key: 'C', text_zh: '与回报完全无关', text_en: 'Completely unrelated to rewards' },
104
+ { key: 'D', text_zh: '仅 arbitrator 可用', text_en: 'Only arbitrators can use it' },
105
+ ],
106
+ correct_answer: 'B',
107
+ },
108
+ {
109
+ id: 'mcq-7',
110
+ type: 'multiple_choice',
111
+ domain: 'governance',
112
+ question_zh: '修改 fault 处置【规则】(属宪法级条款变动,见 CHARTER §4 I-4 — 不是普通协议改动)需要走?',
113
+ question_en: 'Modifying fault-handling **rules** (a CONSTITUTIONAL clause change per CHARTER §4 I-4 — not a regular protocol change) requires?',
114
+ options: [
115
+ { key: 'A', text_zh: '普通 maintainer 1 签', text_en: 'Single maintainer signature' },
116
+ { key: 'B', text_zh: 'user 个人否决', text_en: 'User personal veto' },
117
+ { key: 'C', text_zh: '超级多数多签(2/3) + 60 天公示(宪法级,user 仅是多签一票)', text_en: 'Supermajority multisig (2/3) + 60d public notice (constitutional; user is just one signer)' },
118
+ { key: 'D', text_zh: '任意 contributor 投票', text_en: 'Any contributor vote' },
119
+ ],
120
+ correct_answer: 'C',
121
+ },
122
+ {
123
+ id: 'mcq-8',
124
+ type: 'multiple_choice',
125
+ domain: 'dispute-verdict',
126
+ role_filter: 'arbitrator',
127
+ question_zh: 'Case 2 物流卡顿:卖家提供发货单,买家未收到货,物流方失联 45 天。arbitrator 应:',
128
+ question_en: 'Case 2 logistics stuck: seller has shipping doc, buyer never received, logistics gone 45 days. Arbitrator should:',
129
+ options: [
130
+ { key: 'A', text_zh: 'release_seller(卖家无过错)', text_en: 'release_seller (seller has no fault)' },
131
+ { key: 'B', text_zh: 'refund_buyer + 物流 stake **优先赔买家**(不足部分由 management_bonus_pool 兜底差额)', text_en: 'refund_buyer + logistics stake **goes to buyer first** (shortfall covered by management_bonus_pool)' },
132
+ { key: 'C', text_zh: 'partial_refund 50/50', text_en: 'partial_refund 50/50' },
133
+ { key: 'D', text_zh: 'liability_split,卖家一半物流方一半', text_en: 'liability_split, half seller half logistics' },
134
+ ],
135
+ correct_answer: 'B',
136
+ },
137
+ {
138
+ id: 'mcq-9',
139
+ type: 'multiple_choice',
140
+ domain: 'outlier',
141
+ role_filter: 'arbitrator',
142
+ question_zh: 'arbitrator A 最近 10 次 verdict 有 6 次被 maintainer 复核证实判错(count=6 ≥ 5 阈值, pct=60% ≥ 30% 阈值,双阈值均触发)。A 该:',
143
+ question_en: 'Arbitrator A: 6 of last 10 verdicts confirmed-wrong by maintainer review (count=6 ≥ 5 threshold AND pct=60% ≥ 30% threshold, both triggered). A should:',
144
+ options: [
145
+ { key: 'A', text_zh: '不处罚,投票自由', text_en: 'No penalty, voting freedom' },
146
+ { key: 'B', text_zh: '仅加 outlier 标记(信号,不触发 deactivate)', text_en: 'Only add outlier flag (signal, no deactivate)' },
147
+ { key: 'C', text_zh: '触发 auto_deactivate(双阈值均满足 — ARBITRATION-PLAYBOOK §6.2)', text_en: 'Trigger auto_deactivate (both thresholds met — ARBITRATION-PLAYBOOK §6.2)' },
148
+ { key: 'D', text_zh: '永久驱逐', text_en: 'Permanent ban' },
149
+ ],
150
+ correct_answer: 'C',
151
+ },
152
+ {
153
+ id: 'mcq-10',
154
+ type: 'multiple_choice',
155
+ domain: 'governance',
156
+ question_zh: 'arbitrator 对**具体某个仲裁案件**的 verdict 是否可被创始人 veto?',
157
+ question_en: 'Can the founder veto an arbitrator\'s verdict on a specific individual case?',
158
+ options: [
159
+ { key: 'A', text_zh: '可,创始人是最终仲裁', text_en: 'Yes, founder is final arbiter' },
160
+ { key: 'B', text_zh: '不可,verdict 归 arbitrator 集体,创始人无个案 veto(违 #5)', text_en: 'No, verdict belongs to arbitrator collective; founder has no per-case veto (violates #5)' },
161
+ { key: 'C', text_zh: '仅大额案件可', text_en: 'Only large-value cases' },
162
+ { key: 'D', text_zh: '仅 phase A 可', text_en: 'Only in phase A' },
163
+ ],
164
+ correct_answer: 'B',
165
+ },
166
+ // ── 短答题 1-5(phase A 简化评分:length >= 50 chars 且非纯空白) ─────
167
+ {
168
+ id: 'short-1',
169
+ type: 'short_answer',
170
+ domain: 'meta-rules',
171
+ question_zh: '描述一个**违反 #5 不偏袒** 的具体场景(≥ 100 字)。例如:某 user 通过多签提交协议参数修改,maintainer 因为该 user 是早期贡献者而跳过 review。',
172
+ question_en: 'Describe a concrete scenario of **violating #5 no-favoritism** (≥ 100 chars). E.g.: maintainer skips review of a protocol param change because the proposer is an early contributor.',
173
+ min_chars: 100,
174
+ },
175
+ {
176
+ id: 'short-2',
177
+ type: 'short_answer',
178
+ domain: 'iron-rule',
179
+ question_zh: '列出 Iron-Rule 7 paths 中你能记住的 5 条(每条简短描述)。',
180
+ question_en: 'List 5 of the Iron-Rule 7 paths you can remember (brief description each).',
181
+ min_chars: 50,
182
+ },
183
+ {
184
+ id: 'short-3',
185
+ type: 'short_answer',
186
+ domain: 'dispute-verdict',
187
+ role_filter: 'arbitrator',
188
+ question_zh: '解释 4 种 dispute verdict(release_seller / refund_buyer / partial_refund / liability_split)的适用场景。每种简短说一个例子。',
189
+ question_en: 'Explain when to apply each of 4 dispute verdicts (release_seller / refund_buyer / partial_refund / liability_split) with one short example each.',
190
+ min_chars: 100,
191
+ },
192
+ {
193
+ id: 'short-4',
194
+ type: 'short_answer',
195
+ domain: 'governance',
196
+ question_zh: '解释为什么 arbitrator 对个案 verdict 不能被任何个人(包括创始人)veto。引用 CHARTER §4 I-4 + 元规则 #5。',
197
+ question_en: 'Explain why an arbitrator\'s per-case verdict cannot be vetoed by any individual (including founder). Reference CHARTER §4 I-4 + meta-rule #5.',
198
+ min_chars: 100,
199
+ },
200
+ {
201
+ id: 'short-5',
202
+ type: 'short_answer',
203
+ domain: 'outlier',
204
+ role_filter: 'arbitrator',
205
+ question_zh: '描述 outlier 标记(信号)vs auto_deactivate(触发)的区别。前者只标记,后者真触发 deactivate。引用 ARBITRATION-PLAYBOOK §6.1 / §6.2。',
206
+ question_en: 'Describe the difference between outlier flag (signal) and auto_deactivate (trigger). The former is just a flag, the latter actually deactivates. Reference ARBITRATION-PLAYBOOK §6.1 / §6.2.',
207
+ min_chars: 100,
208
+ },
209
+ ];
210
+ // 为前端 GET 端点准备:剥离 correct_answer + min_chars 限制(防泄题)
211
+ export function getQuestionsForRole(role) {
212
+ return ONBOARDING_QUIZ
213
+ .filter(q => !q.role_filter || q.role_filter === role)
214
+ .map(({ correct_answer: _correct_answer, ...rest }) => rest);
215
+ }
216
+ export function scoreQuiz(role, answers, passThreshold = 80) {
217
+ const questions = ONBOARDING_QUIZ.filter(q => !q.role_filter || q.role_filter === role);
218
+ const answerMap = new Map(answers.map(a => [a.question_id, a.answer]));
219
+ const perQuestion = [];
220
+ let correct = 0;
221
+ for (const q of questions) {
222
+ const userAnswer = answerMap.get(q.id) ?? '';
223
+ if (q.type === 'multiple_choice') {
224
+ const ok = userAnswer === q.correct_answer;
225
+ perQuestion.push({ id: q.id, ok });
226
+ if (ok)
227
+ correct++;
228
+ }
229
+ else {
230
+ // short-answer: phase A 简化 — length >= min_chars 且非纯空白 → ok
231
+ const trimmed = userAnswer.trim();
232
+ const minChars = q.min_chars ?? 50;
233
+ const ok = trimmed.length >= minChars;
234
+ perQuestion.push({
235
+ id: q.id,
236
+ ok,
237
+ reason: ok ? undefined : `需要至少 ${minChars} 字符,当前 ${trimmed.length}`,
238
+ });
239
+ if (ok)
240
+ correct++;
241
+ }
242
+ }
243
+ const total = questions.length;
244
+ const score_pct = total > 0 ? Math.round((correct / total) * 100) : 0;
245
+ const passed = score_pct >= passThreshold;
246
+ return { total, correct, score_pct, passed, per_question: perQuestion };
247
+ }