From fec2e6924fc769c22095785ccbf743ab0930fd38 Mon Sep 17 00:00:00 2001 From: Jorel97 Date: Mon, 1 Jun 2026 09:08:29 -0600 Subject: [PATCH] Add reputation sybil cluster guard --- reputation-sybil-cluster-guard/README.md | 35 ++++ reputation-sybil-cluster-guard/demo.js | 24 +++ reputation-sybil-cluster-guard/demo_video.py | 45 ++++ reputation-sybil-cluster-guard/index.js | 197 ++++++++++++++++++ reputation-sybil-cluster-guard/package.json | 12 ++ .../reports/demo-script.txt | 6 + .../reports/demo.gif | Bin 0 -> 46235 bytes .../reports/demo.mp4 | Bin 0 -> 34565 bytes .../reports/summary.svg | 23 ++ .../reports/sybil-cluster-report.json | 105 ++++++++++ .../reports/sybil-cluster-report.md | 56 +++++ .../requirements-map.md | 27 +++ reputation-sybil-cluster-guard/sample-data.js | 50 +++++ reputation-sybil-cluster-guard/test.js | 22 ++ 14 files changed, 602 insertions(+) create mode 100644 reputation-sybil-cluster-guard/README.md create mode 100644 reputation-sybil-cluster-guard/demo.js create mode 100644 reputation-sybil-cluster-guard/demo_video.py create mode 100644 reputation-sybil-cluster-guard/index.js create mode 100644 reputation-sybil-cluster-guard/package.json create mode 100644 reputation-sybil-cluster-guard/reports/demo-script.txt create mode 100644 reputation-sybil-cluster-guard/reports/demo.gif create mode 100644 reputation-sybil-cluster-guard/reports/demo.mp4 create mode 100644 reputation-sybil-cluster-guard/reports/summary.svg create mode 100644 reputation-sybil-cluster-guard/reports/sybil-cluster-report.json create mode 100644 reputation-sybil-cluster-guard/reports/sybil-cluster-report.md create mode 100644 reputation-sybil-cluster-guard/requirements-map.md create mode 100644 reputation-sybil-cluster-guard/sample-data.js create mode 100644 reputation-sybil-cluster-guard/test.js diff --git a/reputation-sybil-cluster-guard/README.md b/reputation-sybil-cluster-guard/README.md new file mode 100644 index 00000000..f16b0dc0 --- /dev/null +++ b/reputation-sybil-cluster-guard/README.md @@ -0,0 +1,35 @@ +# Reputation Sybil Cluster Guard + +This slice adds a dependency-free guard for SCIBASE's Community & User Reputation System. It audits synthetic reputation events for sybil-cluster patterns before points affect leaderboards, bounty eligibility, trust badges, or payout review. + +The scope is distinct from existing submissions for probation reinstatement, leaderboard eligibility/privacy, reputation review abuse, identity impersonation, badge renewal, credit-ledger reputation, and completion reputation. + +## What It Checks + +- Shared payout handles across multiple accounts. +- Recycled device fingerprints across high-velocity accounts. +- Burst endorsements shortly after signup. +- Suspicious invitation chains. +- Cross-project high-score review rings. +- High reputation deltas while risk signals are present. +- Missing quarantine, leaderboard suppression, payout pause, or manual review controls. + +## Reviewer Output + +Running the demo creates: + +- `reports/sybil-cluster-report.json` +- `reports/sybil-cluster-report.md` +- `reports/summary.svg` +- `reports/demo-script.txt` +- `reports/demo.mp4` + +All data is synthetic. The guard uses no credentials, private user records, payment processors, wallets, social media accounts, or external services. + +## Commands + +```bash +npm test +npm run demo +npm run demo:video +``` diff --git a/reputation-sybil-cluster-guard/demo.js b/reputation-sybil-cluster-guard/demo.js new file mode 100644 index 00000000..a6a5ec76 --- /dev/null +++ b/reputation-sybil-cluster-guard/demo.js @@ -0,0 +1,24 @@ +import { mkdir, writeFile } from "node:fs/promises"; +import { auditReputationSybilCluster, buildReviewerMarkdown, buildSummarySvg } from "./index.js"; +import { riskyReputationPacket } from "./sample-data.js"; + +const reportsDir = new URL("./reports/", import.meta.url); +await mkdir(reportsDir, { recursive: true }); + +const report = auditReputationSybilCluster(riskyReputationPacket); +await writeFile(new URL("sybil-cluster-report.json", reportsDir), `${JSON.stringify(report, null, 2)}\n`); +await writeFile(new URL("sybil-cluster-report.md", reportsDir), buildReviewerMarkdown(report)); +await writeFile(new URL("summary.svg", reportsDir), buildSummarySvg(report)); +await writeFile( + new URL("demo-script.txt", reportsDir), + [ + "Demo: Reputation Sybil Cluster Guard", + `Cluster: ${report.clusterId}`, + `Decision: ${report.decision}`, + `Risk score: ${report.riskScore}/100`, + `Blockers: ${report.summary.blockCount}`, + "Action: quarantine cluster before reputation points affect rankings, bounties, or payout eligibility.", + ].join("\n"), +); + +console.log(JSON.stringify(report.summary, null, 2)); diff --git a/reputation-sybil-cluster-guard/demo_video.py b/reputation-sybil-cluster-guard/demo_video.py new file mode 100644 index 00000000..168a17d9 --- /dev/null +++ b/reputation-sybil-cluster-guard/demo_video.py @@ -0,0 +1,45 @@ +from pathlib import Path + +import imageio.v3 as iio +import numpy as np +from PIL import Image, ImageDraw, ImageFont + + +ROOT = Path(__file__).resolve().parent +REPORTS = ROOT / "reports" +REPORTS.mkdir(exist_ok=True) + + +def font(size): + for name in ("arial.ttf", "segoeui.ttf"): + try: + return ImageFont.truetype(name, size) + except OSError: + pass + return ImageFont.load_default() + + +slides = [ + ("Reputation Sybil Cluster Guard", "Synthetic trust-and-safety control for SCIBASE #15"), + ("Decision", "quarantine-cluster · risk score 100/100"), + ("Signals", "shared payout · recycled device · review ring"), + ("Action", "Pause reputation, rankings, and payout eligibility until review"), +] + +frames = [] +for title, subtitle in slides: + image = Image.new("RGB", (960, 544), "#111827") + draw = ImageDraw.Draw(image) + draw.rectangle((48, 58, 912, 486), outline="#374151", width=3) + draw.text((82, 136), title, fill="#f9fafb", font=font(42)) + draw.text((82, 220), subtitle, fill="#d1d5db", font=font(24)) + draw.rectangle((82, 350, 700, 392), fill="#dc2626") + draw.text((82, 424), "Synthetic data only. No social media, wallets, or private user records.", fill="#9ca3af", font=font(20)) + frames.extend([image] * 14) + +gif_path = REPORTS / "demo.gif" +mp4_path = REPORTS / "demo.mp4" +frames[0].save(gif_path, save_all=True, append_images=frames[1:], duration=120, loop=0) +iio.imwrite(mp4_path, [np.asarray(frame) for frame in frames], fps=8, codec="libx264") +print(f"wrote {gif_path}") +print(f"wrote {mp4_path}") diff --git a/reputation-sybil-cluster-guard/index.js b/reputation-sybil-cluster-guard/index.js new file mode 100644 index 00000000..7ea07a87 --- /dev/null +++ b/reputation-sybil-cluster-guard/index.js @@ -0,0 +1,197 @@ +const SEVERITY = { block: 3, warn: 2 }; + +function finding(code, severity, message, evidence, remediation) { + return { code, severity, message, evidence, remediation }; +} + +function groupsBy(items, key) { + const groups = new Map(); + for (const item of items) { + const value = item[key]; + if (!value) continue; + groups.set(value, [...(groups.get(value) || []), item]); + } + return groups; +} + +export function auditReputationSybilCluster(packet) { + if (!packet || typeof packet !== "object") { + throw new TypeError("reputation packet must be an object"); + } + + const users = packet.users || []; + const endorsements = packet.endorsements || []; + const reviews = packet.reviews || []; + const controls = packet.controls || {}; + const findings = []; + + for (const [payoutHandle, members] of groupsBy(users, "payoutHandle")) { + if (members.length > 1) { + findings.push( + finding( + "SHARED_PAYOUT_HANDLE", + "block", + "Multiple reputation accounts share the same payout handle.", + { payoutHandle, userIds: members.map((member) => member.userId) }, + "Pause payout eligibility and require identity review before reputation points affect bounty access.", + ), + ); + } + } + + for (const [fingerprint, members] of groupsBy(users, "deviceFingerprint")) { + if (members.length >= 3) { + findings.push( + finding( + "RECYCLED_DEVICE_FINGERPRINT", + "block", + "Three or more accounts share a device fingerprint inside the same review window.", + { fingerprint, userIds: members.map((member) => member.userId) }, + "Quarantine the cluster and suppress leaderboard movement until reviewed.", + ), + ); + } + } + + const burstEndorsements = endorsements.filter((endorsement) => endorsement.createdMinutesAfterSignup <= 30); + if (burstEndorsements.length >= 3) { + findings.push( + finding( + "BURST_ENDORSEMENT_RING", + "warn", + "Several endorsements were created immediately after signup.", + { count: burstEndorsements.length, edges: burstEndorsements.map(({ from, to }) => `${from}->${to}`) }, + "Delay endorsement credit until accounts age past the configured trust window.", + ), + ); + } + + const invitationCounts = groupsBy(users, "invitedBy"); + for (const [inviter, members] of invitationCounts) { + if (inviter !== "seed" && members.length >= 2) { + findings.push( + finding( + "SUSPICIOUS_INVITATION_CHAIN", + "warn", + "A non-seed account invited multiple high-velocity reputation accounts.", + { inviter, invitees: members.map((member) => member.userId) }, + "Require manual review before granting invitation-derived reputation boosts.", + ), + ); + } + } + + const reciprocalReviewEdges = new Set(reviews.map((review) => `${review.reviewer}:${review.submitter}`)); + const ringEdges = reviews.filter((review) => reciprocalReviewEdges.has(`${review.submitter}:${review.reviewer}`) || review.score >= 5); + if (ringEdges.length >= 3) { + findings.push( + finding( + "SELF_REVIEW_RING_RISK", + "block", + "Reviewer and submitter relationships form a high-score ring across bounty projects.", + { edges: ringEdges.map(({ reviewer, submitter, projectId }) => `${reviewer}->${submitter}@${projectId}`) }, + "Suppress review-derived reputation and route the cluster to trust-and-safety review.", + ), + ); + } + + const totalReputationDelta = users.reduce((total, user) => total + Number(user.reputationDelta || 0), 0); + if (totalReputationDelta >= 100 && findings.length > 0) { + findings.push( + finding( + "HIGH_REPUTATION_DELTA_UNDER_RISK", + "warn", + "The cluster gained enough reputation to affect rankings or bounty eligibility while risk signals are present.", + { totalReputationDelta }, + "Hold reputation deltas until the cluster review is resolved.", + ), + ); + } + + if (findings.some((item) => item.severity === "block") && (!controls.quarantineApplied || !controls.leaderboardSuppressed || !controls.payoutEligibilityPaused)) { + findings.push( + finding( + "MISSING_CLUSTER_QUARANTINE", + "block", + "Blocking sybil signals exist but reputation, ranking, or payout controls are not fully paused.", + controls, + "Apply quarantine, suppress leaderboard rank, pause payout eligibility, and open a manual review ticket.", + ), + ); + } + + const blockCount = findings.filter((item) => item.severity === "block").length; + const warnCount = findings.filter((item) => item.severity === "warn").length; + return { + clusterId: packet.clusterId, + reviewWindow: packet.reviewWindow, + decision: blockCount > 0 ? "quarantine-cluster" : warnCount > 0 ? "manual-review" : "reputation-clear", + riskScore: Math.min(100, blockCount * 25 + warnCount * 10), + summary: { + blockCount, + warnCount, + findingCount: findings.length, + userCount: users.length, + endorsementCount: endorsements.length, + reviewCount: reviews.length, + }, + findings: findings.sort((a, b) => SEVERITY[b.severity] - SEVERITY[a.severity] || a.code.localeCompare(b.code)), + }; +} + +export function buildReviewerMarkdown(report) { + const lines = [ + `# Reputation Sybil Cluster Guard: ${report.clusterId}`, + "", + `Review window: **${report.reviewWindow}**`, + `Decision: **${report.decision}**`, + `Risk score: **${report.riskScore}/100**`, + "", + `Findings: ${report.summary.blockCount} blockers, ${report.summary.warnCount} warnings.`, + "", + ]; + + for (const item of report.findings) { + lines.push(`## ${item.severity.toUpperCase()}: ${item.code}`); + lines.push(item.message); + lines.push(""); + lines.push(`Evidence: \`${JSON.stringify(item.evidence)}\``); + lines.push(""); + lines.push(`Remediation: ${item.remediation}`); + lines.push(""); + } + + if (report.findings.length === 0) lines.push("No sybil-cluster reputation issues were detected.\n"); + return lines.join("\n"); +} + +export function buildSummarySvg(report) { + return ` + + Reputation Sybil Cluster Guard + ${escapeXml(report.clusterId)} · ${escapeXml(report.decision)} + + + ${report.riskScore}/100 + + + ${report.summary.blockCount} + blocking signals + + + + ${report.summary.userCount} + accounts reviewed + + + + ${report.summary.endorsementCount} + endorsement edges + + +`; +} + +function escapeXml(value) { + return String(value).replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """); +} diff --git a/reputation-sybil-cluster-guard/package.json b/reputation-sybil-cluster-guard/package.json new file mode 100644 index 00000000..51ab3741 --- /dev/null +++ b/reputation-sybil-cluster-guard/package.json @@ -0,0 +1,12 @@ +{ + "name": "reputation-sybil-cluster-guard", + "version": "1.0.0", + "description": "Synthetic sybil-cluster reputation guard for SCIBASE community reputation workflows.", + "type": "module", + "private": true, + "scripts": { + "test": "node test.js", + "demo": "node demo.js", + "demo:video": "python demo_video.py" + } +} diff --git a/reputation-sybil-cluster-guard/reports/demo-script.txt b/reputation-sybil-cluster-guard/reports/demo-script.txt new file mode 100644 index 00000000..f44ad801 --- /dev/null +++ b/reputation-sybil-cluster-guard/reports/demo-script.txt @@ -0,0 +1,6 @@ +Demo: Reputation Sybil Cluster Guard +Cluster: cluster-rho-17 +Decision: quarantine-cluster +Risk score: 100/100 +Blockers: 4 +Action: quarantine cluster before reputation points affect rankings, bounties, or payout eligibility. \ No newline at end of file diff --git a/reputation-sybil-cluster-guard/reports/demo.gif b/reputation-sybil-cluster-guard/reports/demo.gif new file mode 100644 index 0000000000000000000000000000000000000000..e7ed2ba27ff971269dab614c303629af4831e1af GIT binary patch literal 46235 zcmWidXHb((8-BSp?2nz~F{zkluh z{_$(?$Io9oyFa$S?{0kCUR&Q>URhgM`Z~Y3Jj-18G(G#_x@wy`tLs~@HppwY3@CG*1ad0`6XF*>6y7jck&+H&ZTGM+`pAmd^`Jo zdiKM#tOw~?_tP`)rDhhTWE7>|$*0{ZOu3auyXOG|u?g38jL5^-g=Ux0AF8ZExzI672uf5YHTgOXw z=ZUrsL~936>$C2b_HGt-ZsxWwX0~o-wytJ27tO3Mm|9;vZFRxK!jWL%Y;1lWZ{~Mv`#B)omSE$C~6Q+sT(V(;pJ6v@+wAhDmXb6Lm4H56Q}f!E9gqg>l~BQmXg($ zl+lzpsWE-xgv1GT@e>;2$JLMiAGM>>YGVIKRrJ_@sEA6bh)Ag%kyJh+sU$3+C@iih zBz{Wp=qUj)1p!fc{{JJ#C-NV%yhmhtg=KhzWw?b-O0qa?PCJ|<;O$PUDk{Su002n- zh6CmQ%?kew;QulKP%MCj7B#D<_a>rvGLTZ82!wrw0-;p4s zikdf;yvUY0SLynq@yY02Pvez$f7#x!@I2#~r+iZvtvD7dt1!@G?uvS)9&B9D{rbiUO(;mySKeC`q1{-(|>>Wch_fMKYPYv0SFl; z2`=EzB%@B0GZQeHE6haDRA!FC=jcC|B;;E@mn?c?WsWM5EHh7&&hwv7ktr>oPgQ7L znNL$5l37SsfA7C=OMAI|;kN#-m4!PvgzRF5i9o<&rrC*##Vjk$3xcY4rm{;p4vqm! zxz4^7OL?w0R+sJ)lVz9lz4HQ=@A;QjEEfc~t}fpX8vU#SbMeNvi;RRtL2?ZYq=FA zr4}NUt__uIRkal@9f=Ic2vZ+$I=TCJ{BZMMZlR^_xa^U?%6%!-4)bzZFq%IVq|8Wrd^nULS=@%<>D z^K}0ghrlx&WMhlbWGpM!i!ut>uHZPiq3jC%%lEyX@8;*QDnX~}D^G<5r&ot0?rNym z9-{^~4v6`k-+7_%wYhOrwoPHzL21EZ_oa4Mc$2l>*9|obgExFXUYn$;H(Q+%tWiH> z-v9Q;q@Bx;<}sBsAuTrN+H!urb5&~oY2k76)D666nZvKCOAlkSKKWmJb;JB}o7nZ~ zV-u&^CT~!4_GXN>SpPC-V-_$GXA+TLuFi=_hPJ;*^?SQNFJcszxtMXzD)RJQrw3un zyjN;}Gaj7b`}1}G_F=|q$@8=*LRDF4=(@Yp=AVtSQFs20X1}y(iZl~8Aq5&$i7Gj=LS6BsmeC>!$;+aTuzH-0yo?~;hyy;%mD7hodS7Jvbc#s`FR@FMz5B&StHWxiP z=OtPEUQkBH$JZmdW`rx=`x)yJ@CrYAt}oYWawtTG%#tM7~uP$mhYh{)&CqT__4+PN9Y1D>7I zRbZtiMO=wl4E9ep5>Z|!ELKGaE2T5N6UYWZeu+C_lS9!VbNL$J00|I*Ry#x1C_@q^D9 zyHFN`M|ldZkruQz&Mpj+431MJHAMX3*Q#=*d9$LyzFD4h3yzej%~wi!`=_; zSFanIsK8JXOn|GLd{5Tc8D6L(xrYN_a$q7Emq-n=8CHmxLXw+vk5XhHFw8iKX9{u~ zXCX)AVeA_beLFa_PUhR4I5-=4{H#?QFe*D5@!%NjdV|!(?=vYsRG00 zXw~)j{fn85L#n|rZpy}xDFE+i#~z#UC4-M)4XhX-fio*CRGH9~_7b>xJYmPnQ5vo< zoopOe-w!4APhR|Sx<8gi(iWP?GJmU?D>#qoiGm&LEZWD(8D_+o72i+8;4o{qd{2pZ zGuezHKHQYy@-c3eBzTyZq|X7zC{ki2E#a z6^?n-^C4!U5j0Ya5Jix~`2^&xdj_R!{#z=ATy>mlR_>rS87J=W#vGAR&vKZFz&k8f7g1Dsh&9Ax&-9Og0#y>wg*`sCc0eXC( zAJiK5sV=czFCE25|4Rl7NY?=-9HGJ~wg)6DbN&Rl>g`|{en4IeM3(`KaQ3-vu1*F_ z>B)JEyI}Yp_P8cE)I#7;M!p#5`itZ0WU`U8JlRwdUbaOM)q&X`s1HQ!7YX*l0fJ6a z*bxK(34_(+xOOry=W!$r3GQ`qnfc!DRBFO9(xj>r?h;AdegoVTA(9S1;iX@u`UrrHU4jZjYlozJJ$YT6k4BN60uJrlrQJJDx2{quWJ0vF4p68mZ;a_bEEx6Yg0f_vUF(~Ofc&thxfv|ybE z?t&Tcsd(0)>(OI8F?VeNI?zo7=?ubgyE`lptA%ME9^8 z$cb~hdADNyGh{VE1C3l{CPK>mww?(Jg%8tnpkaG4om1v0Iy6$5lYK78C=C2Uy8f*t z>0}C+)<(eLz*l=29G=AT`s7#IDVP1R7`9vl-UA5p@TwrfGjsHsb5L_RdM5WII|xHK z?l3eEmywma8V3OJtnu8~y<8pB?2?rK>Lw#4QyWq)<0@4DYJ!B1HnQ})h~D_ON#J3a zJA0Tf+7B?g3I1hL5Zhd+k8#)bl8@-*-C#nw#{sL~*lY&j4vRr8sE9)T#vT&M01=S5 z03I-$_28WL9RxHZ4arSS#&I8jXbnM2$?<&T9M*;g{3L?of)C*;HfV+|G83DL1dzms z-YFI#5ugnUID@_(T%P5y$ECjrMd2~%dWcFr`=YQj%(D=kS*X`sSpEUvpGX7%TaG#G zAp?6*kNus2-6LXu+0mU>)2BL$W_}mVbr2SQKN=QxKr!fuUaVkc>hIoEm}w4V8?ebJ zMo407ogf?&=brz@qHpG+8`v%mM^;4^UA$Mcgyt@05K_V(37$?IU=VJVf^S+0zh%?) zOQ7fpc71q;fIVjd6WX#@EUW_(8H8?@6R0c*WmB;+qk}dKLKE?UPf98J1t?hgL|`uC zzQvWP$YN7FC#*_>YbU|I5+tTZ4V>XVxLbnCjD7Z&3(uZeBg=iclW=9N64ikDQv%kn zW~;ov-?4KaT5P2eW=CYgkJ6o7GTc!r0gfHu8FnCAt~Bh(8T}uKcj$yE*@R0K;CBE+ zv4e@-tqD$j6l|JE!3A)5a_BEQ$8-_`X29DKQMqpUYmmx3__hQxQYbQ z!3zE6Z1k0yYorRk$}FUPAdqqA$e(=C)S^5z0A)fhDRcZ{fXB>g09+|{l<;va=%_Y# zvmA;YU)A7UHJb`bvhu;DsM=MF`=?w$IvPkw1xuK@-M{0-=TbX?hgXHnP*-Y9&_H`d zjoxAfA`_z@o?j4HB!92!-iul`Nv^VOgb~Sf@*N@cW6QOu2YCUH*e5t+bsqvG1iF}G zW{vw$0^kyAic6Be2+`{D*;J|CWLXK zRT6A0bL`iHzF2VQPBkGUn~F@@>wKH$bU~tgt9O@~Ul0x0?m!gh=~3>joM}#?R?A$f zJ~Efe+U7(I0RsVG+;+2mGxaP7V3h{GXApvNTbP}t^Pfsjp<%UcR&`yq0rx9%bz3+* zu{Qfp8HwxaYx3DBon&oCrQLuC(NNf1wBglqccf>9Teu-xS{tF!9O-4xxr&eIToUOz8v(T)@Zg%`u!sc9R~m9160l+5!lD^E zGmMz=ENlau1ze!SN-jK9Km66lm?1>5{WU9aGy|DjX(p4>$_5$HlOExQ4D-!lu~GMU zJcrZtz~%H_*7yj>KH6wCdK&Wrh3^7DcJ_(xu6teGf8`6R`%n`wgC9>}WcEaz5q;^q zY{lqpIgl_~g)Y9YtDmqJ_F5lkM{rYH_49;|qdw+=PkrHbEUTy2*TKJ}>j+{9yC;|T zb+Dd6sCa>0i+q|C)V0@9<5O6%I1Q>^L|prQ_KD7zBqt#7>Ul*pcmQB7fe!00u18ye zLOp~{{ny4J+y+aKA?M+*rr`P5cX0e9?8@YB<>aQzIA*%}PXYM*)A)&l@iyKGy_^Vi zCYN9;p!~ZF(^ARp`HI~$>x(>iiL)6^hF48fD{ziMZlLd<;cr&S_vA2$F3@Lt;)Tdd zgvv|P9x%JAg-vn@V3r{y>3RbmXEcEn&hX+2kgta@N_u7e3ash&+3+4?D7{A<2qPPotu&f?dCEV1(3f64cH2qN_#;S(Q$@m{}J5G~S+ z%0%X+i#tSt_w~WDae@*N6c`T>wZ>wE!^`SSr&YU3t>BKIy}Ixh;gz(X3Nt-|8c^I^{T%2D*cv) z!Sym^W*IOJ3D%j1+t14(B1A|X>{rmvXMp-R5=H~f7y9)O^#NKu;5)rgdkd`DJ}aH^ z8J>wU!T^%>?>m34=$SB)lB?TVOET9VxoxcK!PnrBH+s@5D}F0)7ngV?v3NzmU%8RJ z7o*xqC|%zGfK7ztCXBqwQN3CiI!<{(&>>nHcz@kfnbkNk(T$1Vw9ACzv4U&RQhD$L zkr<0^TQ{GAO`wd@0hl~!QMFbRc2hTaOPC*xtICtWQ##T#sJ_NJL#MH7XqSw6sEGoo{`Bg39Y=daDWxQ42sMWw*5GrslY)IMmID>&I3fTiaA(V&esGiYgx#X)14FG z+77Ti!l7c<3b)&Ie@!^@`nyD(r>he9*KWsvvJ-v>++x1tQ3N}~ZXSk;10LW{YjA6X zU}*<-hxKqOBgb&qISGstZkt%t{gVyez0I`>a>Ul65m)B*24IYOu33;niD zj_)|8F}&^2fFcvKQ=OL^LNP!+iG;J_&s0!gE(&zSZqhRG_2YJf@o54_ zm5obnPrI`TXyz}ZyK8$od9ep?*F369it{&2VsE*~mJUE2%CE4c^YWuBp%HYBwZWt# zI#F=hEa`!0P61VA?^7P_m##_0^fWdHyrtH_6%@!8h5DDyntJ^haQf~wbW6-AS@gn= z_ekz3kGOOzHQ%u!*&x$p;mXvc3emr?20PMJYT50$!6}k3>y-QGc$o85F|QEvwf(h=`=*UXs;{1L zginNC>6+uX_5D^${hhr!_)&vbHuO!Y0-9>vNZ3{vl0vqSBFj{kw{0a<)k)LlSD6On zl88#(^sJ!GmRaw|DYE3k`HdpE{pc+~buq=FZ&pS+v;+PuO0jcQLX{if`yIGwnr`PT zqcU;ZMAiKGUGK&hRNOUHi&463mO9z$TCnhzTsu`)D*k@){jy;g@%A}B(k8@dpZ$5# zv}S%yUs>gT;1QZ}%C{;gX?t0m2Y!|)Ua(R}6Fi z*L}-gbJ0=HVhrD?E#3PpepeplMV7+>h?rqKAW@PoByjuhDTp#LxE@#VDMoGVh9ssM-4|2&TwEs+f#&vf0Wd233;deetjs1U{cE3_UK>GBInR3p z?w>BM`!5=~FZHCP%{_W+@UDv7?o!*M*z9H=KtT)!JElqBVZ(q&lo=#83!(md<-_XO zLTybmItf7>mlhui#Y3TRt_UF6P9L%7L{rr9giIq2PZsLfIWtJGBW9jlArb|bBst{0 zJ}$|NpUr(&cJYD~j18qN0X=HQ{bOQ>HD>v`F$6PL3`1~%3;5M(a%c9V{;4dDdtd1u?-5S6+Y&?@X# z6#47I46jI+UzXqz2>^o11D3@@mp8SdR?Eu1G{jfc?L}?eDT#>QdbU^1PsV`AnBCWB zjADO&@Ou_}qUENz+Wx{rv9o`+_P$sHfsAMIEEbXou&q4%%^9Y`rcT_$wBwFP4ohMv zMEG%SJi8-E7MQkT<9EihxO5SsBH%DWSKF8;Z=7*c^?o8CW)md@G>$I^?Nsx zv<5u6u16RPSkzNl*XFn+wG-v9ac5K`uh_WOz3HwP{q-8Fj-?AYIlhkHw~ z=?wGxf=O}G-ctM>W~Q2|Q8a0~q?nGmh2vz_T`L~xzh&lDHzuuWYZiE zfhYc^8W(NT=c^uzumzY6{LX8dzyb!QSS-r#mFM9hI7MBSV6G*56OrAo36Gl6b91WUhJ=W)GjGkV)$kXaa+yRc8?&1vxn`D_&0AFuLpCiG?|#bsvaeH$ZbL<1_B_~RFj z_ZK~dQ<{#Xp$JeGn=-;|JJCL!Q_f{yDdu6{mziI`+SGp|NXPX(9hFT5c+B7?&fAdk zAN>fih*a$p7^cQc0o9h=bfuZ%S#C>!6S4f#Kv4qn%3z>bPVfXT58*XuGn5GKyE|+zEPQt|9jCnn`}f87>tSrtBr^Xn5zexP zsLMU_I5Zr1=4x0QA=k&nNsHvL|9Cac1CxpB|NV^LJzYXNBaJ$c2sMhZFk(nRz&G9k zu8IvQHPlbmXOGC)X8s9A**V6L=+EQj-V+?*WXVi5m2m<@YB#aFZ2HQliBBM z{8-(R%gYlcSe|Xb(9~^h{;1$PjEBa+y`1%E{*UHX&TA}M)kV~7783{^L zHiia8p$vq+L(u-D30u4-{cq8HyjsILC^?khbAS!=C&54LpOKbkCX_i(wKNAMAuFjEGb$qpAYeXm{Wy)%Jbm6&jBKS3#tb$Lh< z5^j@2g6T~SJ(oP|ri2?fLL`zA`Xrc*D{_}-Sliu^ap7{)|R)VF)tJpA*n?Wt5#-M`Ii&;ANqO%1bzV&}ag#-Qcth2=Vhb_4cE1b~CmrdK0q|`z zQb{3;sB8_nK6wt`S0@P{@4 zXd0p*LUUA2@zg%RP9zJ0O#i55@GUSVZ@Qx#a1LWjqBON$dI6@O02Gtks zCrlHb;_7)y$an>av`PQYr#{7S0?nDi(j^Oz16&yi&I=s=bQ8;iIx7mz){1O*P-lOD zR39e`Cql$fy4pDePC7yFt%*T%a#((!Ts2L8G0n(C8-GxTiJ{r&H(;5k(X{5XZ;cgy z7^8vy=FcW32guXGy{2!e@#90@>qD0*CN#j*Q+gaX1=aMqW%a?7}}EhZy~>i`b{0Yftz{LP$|) zfw=ZlW@OI)K8iq6gJqxgMPrx1zA-u!-3}RlbPNM@s)yVvite__JkJ(;PBL{N*&= ze625!0c4CV8c1ZSYoIf%X+p3I13D6P^w||Vz9p5fQ7ACU{*T|<-inVcH{ zBsSmZRiSWfkb?x9*AxSq^IIcM2NSl*@_aj>$qw_*j9*x?KB3Of=10nJnmxpqa5%af~2tvGb*+d+R2v zBcPT{TiZR%Y$zJ(}AK?Izdcy4adv0zGHG+IZb0I8za@4DVEkO7EX#E8#u z)AB8)VrgQ-I_}z?M`zlfOVm+CKcwzEF0LW589)p7xeMv+F-4HrpH9>q2WbN*R)Lul z+Sw_k$`RfEJ~$WnS%SWq^nu!rtom$4V<2@7lFn{8lG&UhYiOCdq^ww4b}lLB)?4bn zRetVACBnzKLZ_h!M?Tv7fF#tBh|%wb9U!IY=yq@F3IwhFh8hMzxA&K!J{8CI8z!o` zoKNS@en0F1 z6nkn=5|oLX`*oggU-u6J=!~Q=&PKy-oPRh*{MKt~`3I?`B;jm;iwL!u>LIwL-y|kG zfbe5P3pu6%qh{hMCzZwXO5DM@ynUKA={lCgKF;qpnG3ub{Am6U$?D4m`VCyg%%%sQ zXm{4Yx&~dIMogD85Zo`7m&w@HPfr%B0fF#BiT9EzQ2xpe_?fSP?YCZMCh77{ff$5S;kJpAC&$ zj8}&6=AVY1#}uDRLX@I?4H^nIAXrjong4{?!27#uh&TYkfubg_6PFt&)|Psl50Sn9 zkm37vU%V|FnkV8wwc(I-fl{>DOPFvnDylw7+nLO&R24g_G757*w~t$lv)#Z^rfYmw zV{6~#l5AsXXYJFQT^-h`m&Rbk{G|}Z`3ne7m!YM25JGiK=l#{7>&jM84(FjKx(nD)YH8=+E}WJ>TfXne z;s5+;HOi4|A~gaQvP=vea;yw$Ox5T zA6PqttU87$Xh-UJg9*!oGDH9TD%wyU>3Q6R7hIEaX{oQ@29No2yha2Kf@|e6fuc?S zX<4{H#>Gj%1F!hHY~`FwOOiB<$|@t`(LzOUlT+Wt(ahq~4;BG-?P)(3a(|J3VKNHL zARVuv8Q%AM7)SK4G#6+lrFCcc@wQO&5rM6VHuEF8U6S6kyel03+j=qm9d@ph@CPTQufa3ixnzY{)gCWugk+ip?QEPNd+kHcu?I`rp{}Z;iGq63+tU9xxMD!j#FuuLR? zqz2V@8vCD#n`*-fX_fDXOMJNW-&M4Zpj~CC3*Y!4?_7J6p>7gQJAWs2IFF>J-5C^d z5e>MS$D@MU8K<`y5wyV%v8flI{d8p^J&?bs;4hZ3+v-60`llcME8#Teby`F?mrOtb z`16bW&vQx-FVV-SVQi(|@KVIjc;?SHai|-%V~?Y6qG@}tzg_(D4;kY$7C*HY*S1#< zh8t^zn>dA|iQz2TIP%{P$rc>{xbT_}rJ9wDil-r+nH`)f*9r_bGyFrV2zHqt z1lu2{Jrw8TFuvNKqI*beMnvnOJ?)jOI2xtdn`p>F8ePVCTts>Ysqlfm`sr3Rnp=hk z$OpS5(J8&%+iUU8Ndxal!u}AIXmVF{6eau5ZZgWz%oU`QE5?9tY3$|LzlkjB=^(uD zFn|Fjq^uF8Z%KkAh>j?^;^0sDnaMIc9skE<-!DL65G3;T)>6I-4;`Wt)5;Z3>#Ec3 z`TDm)G=^K|fY0QBFP>Iar(5$is?P5(!%5HY4twM4=BB%(W-7`q-#E0e#Y0@=(#`Pt zXGSc8L*x|o`A4I~2K-JcGxj5^Zr1PTkW7>!Au4tA%}5!fak{a!Wg#L$ed$8s^Gpl?ymId6fU@<=f4jMC16*iX=i|G~wJ8S&B@i6oHEE z$!J%ew@^<~MHdwAW3wnSYQIlMWzNBP{W_&1F8sEKrRmIDm^SM)5#>cBRI6$IuiO#n zw{lWB_s-5W${bVeW>72=^2?6*h+22@RXS8UHUu8mHa1qf_y2hG#gCG{FabELvPk&W z6U%(nq7Yd!8P4miWj+9Fu?RdU07nMM2+H zVq)Q}K}%C}$vBZbzdMf`W9nY!3m-k<{S#;b~D9vu$bq z`DF)@(@^b%LFu=$oYuzFvcZA(rH?i=4iEn9?QU(cj7Si6Z3!|Pl!i$_$hFhsP*VML zQbG|EOX0s5A(<>3Se{4W3*DEbNv3K`r5rDakV=)U+`p43UobVFnr zHlL3i;pRC}5MX$|6z*5~`$XZD5uKBFFHKft6iFG*L(mBk5hv+{Zy&!tBp->Ad6Xje z$>RY@vs0!d(?VDFN$$mhrN`mEQL<%4QGaC1i&Inm64F9-pOMj zYg#@<$=9mB__JKw@#l|xeJ{J7UtNHJoPR0Rqp4u)Ng18IRaD$g@d|PYJ^~`D$ga;^c$Z@{PkC5y^yWyZY-2} zW}!5yGOB;=g>qGp+AE#)?rWpk$Tij1cn*UfNw`^m^$BzNo*!{$A6C@g*jv6*e=F~3 zpz;2~*O=?6u0j7arlg`bt6zKGkG(N<>6x?Ur;x6m=1<3m{%Ou!f2g-di}>85HT!l= zY<@PD!!V+rygRBnmm;rNKPRI3RC_Tq@lQl@j%A$Aa^^*M_4#|zhmnItdj}FLPwpFT zE(?^#>8{s^D@0Y-cNyw!W{-}oZ?>#I?ON^-S=Za@<*1Y09v3ju-+2)feXvs^&(i<# zn9v#Zr@MRI%bVzwyc#u?~Jdw0TC_ z|NJa|`HwitkOh@tBtmlK zP`nYni0jIf6Vo%O-RwTzMmsW@o~t97Va1vX}T9a|h_uDq}hOwTUS_ZhHC89C2mm0QhXu-6xBFnJB?kS{Gub9*SM`KS_NtcMyxE~b(^X7tVcx6-3n@h_R%+;~T#4ka6FzT$9X5_6P}~ej>7fhCa0T>$^E@Cs%i5hXRor;YEcc8i#3#meHk-?++=1} zbIAzAArvh#@@YB1-)|T2qg+NZWPah^*TU&ch zxm^0IHag$h_VnMWu-wYemnt>ehYS?2X0K1qeF%;d?iwm<9RSnpQ!Zu_C3o-6{|IdnfwVj1mc^ zz|8;UWW6V*oWNVnydyAG%yLtv94nkfJYHq+JXKB}wDeqvY*Q9KRHpT_x;&e9GzU%? ze!p@?!5&rIKB)MsCbi{*=cA|XLz=!J>Cey4i|n>Pzx(RS{*8?VN#2fnT_(PE96fvQuY$iJEAp}0uN^vX&5CiN{p-}YANPd+shlBn zPF~ClKPnrtYJEodO``q}EA3N(YSEo%#@?3ecBQYK|7`ZII_~<1$|FH`{hjY;AGhRQ z30Zd&xA_pXtWhtr8Ki^#F9&qYsJc@V>^*wqbeX%RN;co%MbCT&%pTQJ+ zui6$cp;*ml*s*nr{PcUwW$kKlt}Bj~G4tiM?SpEm-_xDK7euM$&y8xwGtvs_(n=jh zwzsdwjOhuJ@}b;x9P+}-V_c&U3J=V|ZU8IGY{C@mn2JQiJ`w!$y@R&RgvDUY_zlAd z#fQCE@p8}8IKe+bIb%OS?wJ)59N+sRB;#>}nG zqBE3Y?9vie3cnt{`1=K&@C#@VGa`v|e}pZDi+3BJI9J!1itxxEh-Z~=XK7_l$=2od zpIP1cH>Y34Ue|uZr61`!Y>FSiBgON*a9!hivo{YPen7h8A1QHeazFb~+V6(GEIGVz zrzDbdChqjT*?&P-@5n4spRRX1Ihx804Z^eNSdwlBcXV<4Mv+NdZ`46`Iw{2bg|J2K*%kBgIpoun|EOpR7T9hb- z!}GM`RY8grLu@((2K|H6R3O5>oWTzhPKH6aogv5f-QX4yY>&kB!;J-{@j``t2d_-D zM4^1@Wa*s5UG4$ZZc%O-h$sdIx1eL~m`2kQFIOe70?E2|ET}*X6SFhJCnEvVCF1?v z04}Bx9}_Z9eY2Dxybp|-i@oC?;672zuTXq(zh5>V&!Y|zgC`nOih1%9jSGqFwaoX$ zMc^`%%T#jb1zf@zuPtiKE7Nh>3Ym7n_&hUZWn7 z?meg=W9dUi-U-+k0(jBuC=cb}lov9Ni25agK1>vTRD7gyF0Oq}s815VfftY_2*{A7 z_1Pr!$=a9%9$c?vI04Umq_{KxfvxEHK0{T8qP`CtpOTOjm_yk}$Z5{YRi2*b7Lx!6 zq7w5d*$^X8Al{ynPlVY1ne|YLcLdzf(yyKO797x zH)w*?r;xG3_>-c2U>HOqAI(XUU;uXC{%QxAz99*g~NlGgyZ48Hc@Vh`wXFk zK1mR7GUEMbV$uG@(pk-=bCg8>eLyU@Pi&vTheJcpmYgnFG`&4DsZv4^fSUv|gS6e0 z>8Ni3VHv;@#+(&FWxraylvkv8kszimN|Yd zkoenLTA&brGI&Xt(JSZ;9ly@Pzxqe8sP(pd>TPw{|DTn&6L`X8oAHwJxn%R?V&0I< zK1of%Yo_HWo`x5yE_E<0mHqZ$D)xkBr?i#s(wUt?_njvmP~SM`+zOn1td+iccpN`m7Ixb=+{W*^;b~H8nO~)MSn3J9P^svOv@OE-+LtFz0xP7vQac_W z&ZB-FJAN~a`wGfFU_Sl?U!s8wMFi8U$45D01u=499t~f%uRON9IxWU1SLdNf?*npt z11kG~6bRoXyWOsYYC~B?C*>$({E`Okc+Q<(zH$PdFA?i1xvL|aQ~5lnl1+S{q`(J1 zMLfROBZD9CzpOfwQYwS5_D}OF#{MvlQ%rC*{*re?79S%krk`Yh=`G@cYwPz$9`+YT z$>tySX9xtGlq=0O4am##;TZaIv^qd!pCp{KVq`+J0xNItl;64fFiW-K1KI77*DC*0 zQ}sM3UOEvg-75ydId4Geh82(8=VX^xZu6MjIb1Q4@p$lU)#%6S!}&Ax_p9`8WNff; zz)GQT#z5fw$%Z5AuPc@X^?M8cB=Uzr@RT(pGuhnt;x&PCwPTdnxP@8)O5MDF>8G_) zW50$x(b^oa8AFC^_R2*J%Lj`S zbgRZ9rS$e0mCJ$uG=lM95n+wMY$cgPEtQ_-I^Z z;AHU2r^!Y*vM6YBQomPH2A_6xDfrW=@j$W9p&MZM#xL_z@4ivr>4rpsRqCQuSbcgb z7v9x^RclOg0|JTa`wW?Kwkhc9FR|K`6QQx+inR`53uBa30r>OE^+kc?WuAfc&X9TE z&4*!|3w__-jC@0sZj9`#gI1f&Z5QpuJ_lWSJq&)pW>zC?c5AhtK30yUBpRc(H1=^q zISG4FN`I^qUmC9KD0_QlRbtx%@hkmcgxJF)FnI;2&4Z zz-F^WPj%ZhtizgIjuYB6qOS=u3EP`>e*`Ej=(d%10=8sBR$|)-7sfiQ`&~K6{CN3b zOlf?KGKSwY8aScGH(>8L`|HNmUY_y3=_Pnw$luZv?|-iS%LN_=S(SLy_Jn;V>ST*nO%atbxeXB<5 zkEM>P98PZiQn`YmUS1oUT{}$V>&GJmDI)PoqP$fCqj2#Bl|9WX`*GV=&JA!@oe(da zQy%^|%1vyx0r%};1$k0azZWFV9Hp-q<&%X6z8tfe`EpxnPj(S(?=`Bg#{OZ(Mr`Of zBt|YHD?j<-Wyl{=`W^q^z!->>w94*B)#;@j#fML<%qkRk;quJ^Y;ijld0{8YWKM2T zp{#zzc;jvECM(gV``-rS%B81MdKWJ?855i2S(R3#BBg~!#gh$FhF-zOEEvbRS=q8i zx#x{mJ1XxxdU;n8jqG}bOTL_1R}(=#Fdp3vS}PWvJ-KZVu4VhpqHHG? zTt8jKW;42J++U=c-V{^+MdR46&BIDNd5VE$k=0+E$;}m9Dyol}$e+JswI~y~o$%#K zA{Jbg5roTRhi?9K`&G~=e`n3AzR~gF;FOcrYeGL%B$Id*|2pMAtVh zZd*;p8+Ez@Cczfody$?p*lH3IIp#!YX?$Rx6PZAf~< z^gn2N+-=qUyFA&^y8q4tPi*zQdBrolm8j)oU&SUNjW6EcTC{2NI)o{hNRM9hbNzh7 zqf8wyaWhWFO)w2+rR44Vm*IPVPxlYbhPOOM5FR5B_ZMu$!Zq>Ezry=(;D=kSl-r{9 zZhmfd5rRY3UJQsINZ_Ynr<#mGyBgyBWFt62P zt8o~&dX1Exhx(Tg{WH}&J^S0H)mHTcnn0?k>t)sGpQ`dI>!z%I3Zd!Jo&QmG@9|9k zkN^Lln_ogO{d&LO-_Q5^z5IT^|6KUX>~h&Wc6(g!PY{&zA17->=CqT0+cg4lWqihw zXChM%-_lM9j@z7#8o@WQ^r@22ZM;%MR5h-CavF+cvP)3A3*?T-5$~WmD*2&1ZSsHBYV4Mm7{a zLXJl#cj#GWI|)KQ3`LxAFY!b+I*a=vv^P%D*hU(|BUTY;G%0%(5ThU^gxS21^pdeiOA>88iIX+{9 z6{VMHD+VgyX_M-a{&uy<7`?@sK@jt%STI!A_-XYH_T`KE`nG!8nXG&7exV%P);R3hwA(W8}9W+lyP81IFTaS~?$%xJWc^K5pC$z4GD(g0y|* zbfHG%HC$lmD{gvZ=`r5R4VSOo4x7{27yLzC3v}wmZasqPe>neD<}M{{XHe~So5Afc z!-fL#JbL7Hr$_d@t((f%&7ssw_);?}nC*BdlGz@e9rWzcf%i1OVqVZSZ^SjQ}SNZjXP*4D+-%3lQh*rwM*r&J@S z4z&NA+B<1{7#D2B*LRVjrLZc-Jc*SR#J9?mhzJib&YsB#ko$R8f8JM4qH6BrQq$u5 zrlo29tj*2N7p$kf{fY#Na%KitWU7hJOkcsBM+7J}Wcgp{BmKK`TZd=+Bd&fa@t9vLJn_hv`|>HMBlUCmLgiM?`}ux+7&C%bbzxfZ zQyY7)+iHcv$t+nTj`^2yCl%g?58b|Ptebno=X16H?5D=uo4ykbDeO$Wyx`UFmK2fj z`bGRbS&P1e)K2n5y6lgS|3b?|Pqf zY{gu(Tjo3UBvf-G?8NI>7v~Ko4j!#BGhl?wU3i!%pNcmU3ilkNwjuVl9yi$AElnxQQ_Q4@8eNZ>Q4My|ZI?n9M0HashI~PirxyFc4kMFv5qy1LlYbg6bS zdKaKr5KMzQAmL*ZX!5nB?9=GgiZ?$MW~!DxX&H2o*vn#Dm)pz{yH|!-@*3@0~ ze#hy=Qi-e!Uv*70lQ6P7!ycoiYTGjzvD~q|E(SM5E?rT*H1aLizklR2IjAG?asbF; ziZ?JsUuUl9uC23|?^T!4`Nu^r+p{J6a&i_*EBc+km(?zhekYYR9bJ6ht@e5G#h~q( zrTd*pbxSWNlg=#H&X<2)9vKfix>CQr{CTArgb<%@%#=UNXhR)8yZTzhtdCJF<$HFm zTj}}O+Oz#DI_teUD`V?#aT7P!^UM%mHs0GEKNmD=*NXy*;=2 z<<_R?W?J~lxvj~#gL~8T3%5`F4WI1ew3wQ}-r-H0U6dXC+w1 zn+OY}vq_gc=iu;;KvmJ%)ji9&eqN0f*`Rac9CLZ&uZ2l#Ov3C+%21ZnD5bzjZnu(L z!EaY%)T<`pgAQ$>^T=4e4Ywb`bLHqgGRZ_>9LfI4aKBng9LQLvu3*?$$+jZEP9szB zNtTJKGVk4EC#Qs3ggd?kRh;ni5TExP_HZ?V)YDP{y+rs8rYFhrri~>%? z(k>}A{h`KJCA)0PQ{|}{Wr1H0xQSRf^{3u@neH*-oo#h)IW@C!8%(e|G zPs?8loIN%va{N|*TEUO1S-sWl<9C+R3V(0R8h}LcMBa1?`;j>uDhD5}mR~c>5uh(%pWI;p0Y3E%_uQBvS62zWB*Vs z9Qq$=^Afi7OQNXPzmO|uzGvW_H6co-P zh*_1D883V1%YRu! z9xRK9r4U)!xmf%+LG&+w$l2J6MG!gstq>Vmo;I{NjWa*>zd}SObpI$sEQ09xe-lJn zdMtv-QsbD#Uj&iaAB9NUeSw#PzIHJF#p)r8Ml7>JW!Xzp0|DH;Ncn%Hp|PqfZV6=^!U?qG%D<(dJD)1e z?BhV%GXIi>PHHTnVp}*X|CWXvMn1dobP(=d8w4`6cN8$+{3xFW%)=Rl0 zEtw;lay&dtv>)0y@1kJ6)$JhJi0j{uX!|@?>~(z=zGGN{#k$gn`wFqMpIOpSm#Cja zw(EenfKyuQDFB1+HEHtzq}iJM9y%CrtElIl0zDgm-xRYH=wnApx^mt5DSfi#6asyL z&XR_Pg(HMl-SAxeOYT4vJB(m%Qs~Js1C$!G^aDk}2?;h(a*{Dlx(#&$T&?ZTP$4#)Pq3+1LkQ!i@0~S$V8Z<*V<@^>TyGb~>CbY=a6M(U=M2B;j;9<2>OHE!D`D z^#`>-JkC79{*?W>V(cy~5TDM?4Pk#Sl;MVlp)$D5O%Ouq3JtQE)|CwcO95mpWVGu5 zMriwj3cvyF^2SZuw!a3+@%W!Nm8-jeI!`;`0SkJaKtuF$pQ69Jg%B zaq^Ds@wgjNWm{8+lT=f*IoN^00~{@cL0KYqaRN?tK<{FE%4MMAz)#nxeQ1tV;$X?) zvpz@xp%Hg{Ny5;z&}&I%RXRmTx8>qf?$F|RoJ+9Fs=@MNPZ}&t*b?PJVWVuAj3SqR zt%iuUcPx$FJnp=VjIIn|Z^Hy@XMJxWqghg{yP5zkw4uivS`8 zYomWQn9;zN9Jj%7E(o+c=lW8+6BFu)^EBi80W}u3qKuw8O-_D@`pUW0#=0B)%>X!I zOkf`=06BCSHlrC*2bInDqu)Uzwo{s;3 z)}d3o#CcA{S$^`Bx;A>>W%U;zDvzh2*d-jFL&{x2k9&+~69%KFnaJi-5I^=>Y^P9QC&+o70!_?R zQhJvlRonr5$m-I~iHiubZWm2`2C9&Sv4<;`a&Qz~(2qNjh(NjS6Hqc8;~}fKm_o!x z&$c$9Pmn&yK8a$7Uo^bg^L|9wL)FLa?miL)Y@ysCBsdtI!Gqzv*f%XkBSdH-sHP{F_ER5$@yEURKzuC+(SqPlgbgcsL^l38cdGGg0Z=C+lonSC?z$F{riNtNl3t-mUt+3s=due?{?_f;))yVsTX zMOLTvw?nzxeV(>2a)$c8Y1VHu-}oiH$eXpEJ^FdOKe+!z!DipA{?7JW0&f+C(`L?4 zEQj_19dQ(WJq|+BP>wOj3c9DxnWQ}&Om2ccy6`@EA2d*AhSUZ_Gl!pYvFA76f3*ApcJo7X~=Qwlb$ZhZM(xm<^O}u81DW7xBr7K4 zd4pS*48RyNG6VNCUzX{iOk`v>{X+OXP1adYWub zlhHs$aCHG)nocNcKhu?@|IQc@0Ho` zMYC}APf#v0AVUKqslXLR5Od%blW_~_&%SyZtcvu3A;B|fq*o^xh6O94!M_*?fh<6X zL=;s-#yGGGQvn4sn3DvC@xy@GutP}sXaz6Ttq65tTPB8EkbYem4_-Ar?#UOmj|LX5 zu|g<%otce7NfVhg9#%>(P6I0-edpE@8p6H@{UX7jC`0oom}`{87ExL|LfJnCtr*d4 z8hx4+?W}k^uoz)L2ITRl_(8D_Sx!ZHSkU}9WOSKLEk)MN8_7$Xj> zeiw6zhnoUeZ^5-@2}s50(gE)TX=FX?_=5r!7xwk0+buE>ZNZ?|TZqoA1Z83018DfZ zsDwN;Qb7T!lLd^_B*F#~#~q?QF@7INAQ*w`!^!9X{81(a#zg_Xwco-I2k{2S`cq;W z0M<`ghjfXvS-`w!!s1*KlY9djYNaeF^OumMZtB=71CDScQv zSUMfXIQ*LqTG2x3Dxpl2Q05lt21*%5unV?i;Fv6OmIk6_B^S&RZX>}`{3v%yM(-S8 zp@6*LbPwr&@0dq0_rM+43;~iI8Q^t~S2!3cpdTEJ3Lpb_l#sTrV2g<4)LIhK8ToFMvcVrd7!pX3tHck%tEG8xfr?iz5RLXw-Bk=pkE9j#D-Y#g#dNIxd3ZB?BF3)E?5ekAdjS&O=q?!3Oe} z7#glQcI5J2X1<3*2Qg5uq zq4Gwugo=vzR<9y@z$i;p)+IkQHd9FbzT8n1^eF}Dk2t862qq#<1s9-2QG%kVeOD;L zMfu>0)H!KXgZzHOqbQS}doap5p4V|^mc=mFVi=|vl~Sx`%DdVTk96Z&7@_bAr*~1f z!Uov7<{-UUUarcIJVgD5v~v@`vHhCA+O~;^nSBHU9-BV_AEG|K9giUPKIgjy(e zbA)=@RTv&*M1h4cw-RslJie0ygy-DwtcwY-jO`$m#P^ikck)@42UT4}#ftjoK8+a`cTwCd{Wl7XEN85L-fazpkgK=VPHgK_0o|V(SpD_B;yA0n*+*2@K2(xDq@Y z|74UJ!VvW>0eDt>xL1+B%5@aHaKiZ<9t$)mq8e}_`%P?>uhxYuXWbb8#m6OfKXc(Z zkXy!fH;07_m5m;i09AmFRcz(}+gzv~G7v3`+I?jO=SFdaQrDbI^PsH1+#MDVQU0|O z)608^xq}#^0Bf`9symf@ZY(_Fg}xXH``uZMgLhTP8r8yeUMUcj!pWNzuH?#*M&@3? zKxaZK0e)XrsqbJ_zPLc0KboE8T)q^a!yU-G`Y2Hl_ngtg{o9Wau~4v+1K4t-@Sh7< zB*t?jr##Zvb|>*lF5tbB4Wm-kie7piK;8acO}LvQg@Jzp$ghG?i96Ldb`bu#KtQP7 zswskh5WG25hElJIzRUND%Ws_xmAeJx7uAhq1LZr2rB1H4o;a!)s%)nYMy&%^)MLJ- zfng{|?vT4=zzmH#%Lv+~XOs(}=DW+{KR1-c6u4e3cNcqnQS8;6GV+7wAz3Cait8v0 zjZ~Jq+0ZS9>MgD2BNp;tA|Tt1`-*B*aLr1yg)3Gm0SiIG3|raBru~Xde7Gim0s;uN zLir(rnF3RWGYZR)pd#WApop>`V7gdp)k8AcwXt(TZuV#MtZS?c=!LOvrTq*yn9f0nVd%d^r~x%UmBMh0+wEJfGGhWVJxJV5VX|I zbr3x!kK`P2MF39{Bj8`&*?jqAQ*()#+gQB?2F_UP1ixBWLB0bxl5a+*0d*3qJWc=@ zP6y!!YR`5ey2{4-mc}Su?8yos1q`R9*!VOYHQzX{GBBQ`_%;$g&ZP6~EdhWU-T60y zK5#wJ5ry2F0O`}uichSco8T+ralqU_BOzJ&9en4XdFqF;S%!%cPi^sm6mL#4J`Rd&C z_3Zdpm%Xp9lHc6*zj?TPyA<}#v*6p6rf=Tk->&U_^OKytu0I>-GJ7LzHn?Cmq-pl{ z_-xqTEJ1QELVqsGWiBRcj>IgOi*K4s7@tepnA@U&^++4w^F-U3zfd!_#ODwprC!oJrOe6MTz-Z1{XY41Bt zaa_OD^(g&BNPhm^L1xuq%OJn0p<9kbV$>k~i zg z0WD;3H8Xf77`#jdQfigYU{&D!s!;fUd8PTM_r%X@ z%%6Tzo7W9C1J7^X2;U4Y+ze^nygjiQ#@r-GZABPtMV;S@3Ev_WZpAlmB}{B3F}KK4 z+o=ZI>F2lag>PpSZs#;_=S^%EFt;gEzwR6SDn9?~QTVTt!e39De?6P{RnGiHmD;H^ z*r__d!#b|3Dcq@R-f5WFX=3isq;^{kcH7VIc7*SC74G&l@AggX_A_?}q<+6M`2FGh z?@!^shYNp?Hvb-DPW&Ec{-#UqO(A~ox$J!l-NxyD8&%K~9^Qb)Ydw7+|6<+1fGS_OK@4s;$XVjacre!!(-*wmY+3Q3F<;!aLnMd2z#91#zUB0rd%?ae)QucUcS zGyb?VsN(zL3pxRarM$CcQ`Sr6N{2N<_8s*r<(aJKxqs5LJMw}c5s8YZ2Gy1#tq4^2(8J$B}OnVlhA!n{NO{+20HnlLae7NY28NIE7Y zIM=5!WWOqHDK^j;Y(*7_V# z`QjOZxc2bl>BANsno~q>{b6*Rm*n$h+7VecDsW)yM-AeyXVH^MX z2LJii`htL^eSBZXt|T6KjioWzzvFmA^8>#8)P1jCHv;#~Je+%hbXj*s>A7?t+xYrk z5hoK3Od?Yq*;@$%>?+<<2u(b=U30hv5ra80NCEAKM!-b19}seTU9!7kbUHDNI|yB9 zk0+%v+?o;G9ho~O3T-A-Afq@ZDV&9KMw}f7Lwu3qllS)3ePe$fcY2LDY8^d7*X_JIFwZTW#k%u&hQs;Zxeo5|w5xq(3K?D0cAz+v&#U0&70ZIQ-lpWEC z;CSMg?U72vh+?lu`T!p!3kXR>NF+zR;|xKg+kzO(m(DrD22YhmI+A!zG`b#Oe`e9N z`|Z#{4bvr_)Vnh8Tu}{?cx8v}g-eS{ap;HR&jIIm*(bEOsmw7Viy$* zvayjEc|@%>8@!d#5w3VYCQ@Zant$8U%AHTMvip)!bvHRN(GdNb0zxjMk=F-Y`QMHe zYaZWz5RQCD2IGolm?_d8%Ii{nf$~O_ZcB%2WR7e+^g=5ZK^$-=f$9};9xvGU&%Bd5 zL5sjnZ6i*`Tt{=9dTa=nG0r#=h(?;s;+QFTvb%@Tpi$to;4Z0R`3%+x_W%@FFE|T-~+*9mS z*C701jFbuCJGQteYFR*5Qp=AGmjzOctcv6a@l!J7xjWoCiiR`Uo!Hi z3$b~z!vhCDRd@W53iy51mGjW>&6vm3SRax>I)j54*b42bo1Rwgb)Hkk6R%~Io%O{I z@jtxr65&5{k()qLsDi z@k-QKWKX3_-V>Q{u%f2ype-fN&YDe7tNjI&HY>y^dU`=26uH-mt**zQ&Ob@w%d`~2qd%zWu+f?|Qu|E0__Ew%tSm0_;&5G4diLl+roZ}? zjGP|4zTHy^J+9Ml18GvfJ4?T~&Jq${nZ>G^ZGuujR zvCUGfYa3JxpC~!Am5hm+G+utq2LTBATei?SkzX2^JRgT*#;;Lom zB9sdaJv@UZC+7Xx zP6G|cj#FGdMoZR9sW;Bw`#jKh)iyF$OLmrxSZi`K6S*Q-ETDmm84Fi+*gw}MbzHdZ zj^wo<53|lio5vD3&m85PfG10_`)bC;bT`8b^|U+a+qiKxat&L?8veYt_lM;zPHu?Q z2}U(eX0kclLr-XgLR605OHQf&l`&FBY=)~bpGG3b#Hmu1hMF<32>O2iD$YpwQ9Jls zO5~Knl-XM5#BM3StcXU*2=-Uzky(cA#JJDz>#hfP`j@YtTG8C{Dlfc4^gb^==Er_H z-8K2gK93#R%DTt>=eNHx+qOLv>OPA>jg0D&PSk}D>qQASO&x1$8fl(iZ(cYFeaFXs z0pPy_fN?b(NSyxO1ASnF=aV^YA1akdFxc*W8C7Bs;b-u+S5Xq9rh4_@z673GF0~6l z4RQes-ED3cZHb{LoMq$mJlwMNfVjPb%Pj)+MBbMZC&|h}cMp>UKj`-s;Q}6jro^Dr zCl5VQZ{0pXQlo-)SRZ^j3xom@29E4ZF-O&~^`<-D^@&}L;9igl`enFhq*~VgiD^zr zbEN{Mh$JP_tuD|IA1SdVA<<2R2-LjjL7K>tOm(3_R3ZkWrcEJ=1Q?AzAg;WCYuFoU z8tbfE)rsoBEvt+pXzd~gNS*`W{1AE35)S)@cI(A9gQ#5WqL{fj)Bs4HpmNzU!nTXtwX7iMn|32`Z@5ucPN!sg#oGF zPuDGb!ycIjwmvk*mYDm)Z)}rT#qAUSr{w2r5c%4bG(Anx;+7|8(AI_>-Wwg zO91-N!}75)Nf)qWvoE)K*0^Zioe@P!=O?Xpqe>S`!x@TSMU5q>5y9pe>NUg$>E7a# z<%KF%MmuF6$d)xlJ?F(W1W~4JXRBB&53$RFsAx&lw)D+TXz(a(^d_+$6cs{Z@_~pW zBui08%SOoImHUZtVttHI%K{b?gtvNCtXC~=9!;`(22qkbU-3Q`prx4-fDq9`Ui^`71FH@>sbM49Z%1Mv(1ZQ z(AQL3d7O2z_!}12^1)a^6cce6%_fPF5addyLsLdd8xu#sb~Q(`i@O785d&Qi92K-5 zFTGv-b^*tE08?rsETvP^MnuOBykoQ40!x@{g_WcnVL(jr5eM<$(6-iXSxy){k*jfl z$AomvGh$*gLB1>I-i-0_v6Ksb$0KUg;d)T&F6TA;aj3K%|3i>~390lJ*rE%9p@6KA zByov+ej7XH{()ndfqnJ+>vQnP*Le7md#<{ycbU-L56Aa5j)%G9Iim+G*YR902bA=T zMIB9`LS5FXVK^0pdY)w15i9-!V#lfT-yj zqai@@H;+;nAgZCGL$sxZUO=wu352|Kxc$*Vj8PdB9i`X>IzWL~y|=vb+a!#@T6WT8 z`ddOpe{&9Kcl&D(N1bzw9*EXZ1WTeLPm>NLnm9(k)L^DT0!$pPr@{%1L$|*;H03om zf9R)Gsa*SU+D{I8Bgi2*V`zcsM9d#aMA=6$V);~G6lc693Oi@Z4eR(M`Ye6&g%6Fd zIkZBYQshPs>p4IE;+US8W#(gcsEtiBIKmwL@LWDG>w^Rdzfa-8qr|U6&)$qY{puv> z&3bZ0nBZd-(f2=n9!*I+@bt?_>79=iK{jnKozFUr1lTxG^+uBPJ{0&2-Ar_l+ZiUy zjm2dQ#td-En?ssOqydR@?|zfq{Yr}PU&v&O4?p5cm9WDXp(78^CDCH_=A!O*eNp(r z9yio@E|1Js+x>=aLz;X@oI2u?u*IR{XG8HEpZx-*pL0or{?*QbN&rJZ7p#1)q_l!n&^>%YWrcGO9zFXr z+4u0--;;g$MgJ=3@>s)tl#>4u(PifsXXZc7%q?b3_OZ76SRGw@&clrCqCfduHmjY> zXBBjR=X2zY0@ill-x1xv7ySO3@5^BobgTtG)_fl;pZn9!CFhZnvPlVl^0}CVjOc`H z)|B5r5naZ=NBmd?9c#odJSyqG3%b9i{QipQ!bz-%E;#(ppx@2^6m&6v7j�zW~;V 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 G3jYnXCU;5z literal 0 HcmV?d00001 diff --git a/reputation-sybil-cluster-guard/reports/demo.mp4 b/reputation-sybil-cluster-guard/reports/demo.mp4 new file mode 100644 index 0000000000000000000000000000000000000000..cdfa5f84cc11362a02db44274c7907e410506e2a GIT binary patch literal 34565 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 RGX(%Qwh?e+bG+~C{|6pG?#}=K literal 0 HcmV?d00001 diff --git a/reputation-sybil-cluster-guard/reports/summary.svg b/reputation-sybil-cluster-guard/reports/summary.svg new file mode 100644 index 00000000..ff044525 --- /dev/null +++ b/reputation-sybil-cluster-guard/reports/summary.svg @@ -0,0 +1,23 @@ + + + Reputation Sybil Cluster Guard + cluster-rho-17 · quarantine-cluster + + + 100/100 + + + 4 + blocking signals + + + + 4 + accounts reviewed + + + + 4 + endorsement edges + + diff --git a/reputation-sybil-cluster-guard/reports/sybil-cluster-report.json b/reputation-sybil-cluster-guard/reports/sybil-cluster-report.json new file mode 100644 index 00000000..9e067014 --- /dev/null +++ b/reputation-sybil-cluster-guard/reports/sybil-cluster-report.json @@ -0,0 +1,105 @@ +{ + "clusterId": "cluster-rho-17", + "reviewWindow": "2026-06", + "decision": "quarantine-cluster", + "riskScore": 100, + "summary": { + "blockCount": 4, + "warnCount": 3, + "findingCount": 7, + "userCount": 4, + "endorsementCount": 4, + "reviewCount": 3 + }, + "findings": [ + { + "code": "MISSING_CLUSTER_QUARANTINE", + "severity": "block", + "message": "Blocking sybil signals exist but reputation, ranking, or payout controls are not fully paused.", + "evidence": { + "quarantineApplied": false, + "manualReviewTicket": null, + "leaderboardSuppressed": false, + "payoutEligibilityPaused": false + }, + "remediation": "Apply quarantine, suppress leaderboard rank, pause payout eligibility, and open a manual review ticket." + }, + { + "code": "RECYCLED_DEVICE_FINGERPRINT", + "severity": "block", + "message": "Three or more accounts share a device fingerprint inside the same review window.", + "evidence": { + "fingerprint": "fp-77", + "userIds": [ + "u-104", + "u-105", + "u-106" + ] + }, + "remediation": "Quarantine the cluster and suppress leaderboard movement until reviewed." + }, + { + "code": "SELF_REVIEW_RING_RISK", + "severity": "block", + "message": "Reviewer and submitter relationships form a high-score ring across bounty projects.", + "evidence": { + "edges": [ + "u-104->u-105@bounty-1", + "u-105->u-106@bounty-1", + "u-106->u-104@bounty-2" + ] + }, + "remediation": "Suppress review-derived reputation and route the cluster to trust-and-safety review." + }, + { + "code": "SHARED_PAYOUT_HANDLE", + "severity": "block", + "message": "Multiple reputation accounts share the same payout handle.", + "evidence": { + "payoutHandle": "wallet-alpha", + "userIds": [ + "u-104", + "u-105" + ] + }, + "remediation": "Pause payout eligibility and require identity review before reputation points affect bounty access." + }, + { + "code": "BURST_ENDORSEMENT_RING", + "severity": "warn", + "message": "Several endorsements were created immediately after signup.", + "evidence": { + "count": 4, + "edges": [ + "u-104->u-105", + "u-105->u-106", + "u-106->u-104", + "u-107->u-104" + ] + }, + "remediation": "Delay endorsement credit until accounts age past the configured trust window." + }, + { + "code": "HIGH_REPUTATION_DELTA_UNDER_RISK", + "severity": "warn", + "message": "The cluster gained enough reputation to affect rankings or bounty eligibility while risk signals are present.", + "evidence": { + "totalReputationDelta": 119 + }, + "remediation": "Hold reputation deltas until the cluster review is resolved." + }, + { + "code": "SUSPICIOUS_INVITATION_CHAIN", + "severity": "warn", + "message": "A non-seed account invited multiple high-velocity reputation accounts.", + "evidence": { + "inviter": "u-101", + "invitees": [ + "u-104", + "u-105" + ] + }, + "remediation": "Require manual review before granting invitation-derived reputation boosts." + } + ] +} diff --git a/reputation-sybil-cluster-guard/reports/sybil-cluster-report.md b/reputation-sybil-cluster-guard/reports/sybil-cluster-report.md new file mode 100644 index 00000000..e959cd6f --- /dev/null +++ b/reputation-sybil-cluster-guard/reports/sybil-cluster-report.md @@ -0,0 +1,56 @@ +# Reputation Sybil Cluster Guard: cluster-rho-17 + +Review window: **2026-06** +Decision: **quarantine-cluster** +Risk score: **100/100** + +Findings: 4 blockers, 3 warnings. + +## BLOCK: MISSING_CLUSTER_QUARANTINE +Blocking sybil signals exist but reputation, ranking, or payout controls are not fully paused. + +Evidence: `{"quarantineApplied":false,"manualReviewTicket":null,"leaderboardSuppressed":false,"payoutEligibilityPaused":false}` + +Remediation: Apply quarantine, suppress leaderboard rank, pause payout eligibility, and open a manual review ticket. + +## BLOCK: RECYCLED_DEVICE_FINGERPRINT +Three or more accounts share a device fingerprint inside the same review window. + +Evidence: `{"fingerprint":"fp-77","userIds":["u-104","u-105","u-106"]}` + +Remediation: Quarantine the cluster and suppress leaderboard movement until reviewed. + +## BLOCK: SELF_REVIEW_RING_RISK +Reviewer and submitter relationships form a high-score ring across bounty projects. + +Evidence: `{"edges":["u-104->u-105@bounty-1","u-105->u-106@bounty-1","u-106->u-104@bounty-2"]}` + +Remediation: Suppress review-derived reputation and route the cluster to trust-and-safety review. + +## BLOCK: SHARED_PAYOUT_HANDLE +Multiple reputation accounts share the same payout handle. + +Evidence: `{"payoutHandle":"wallet-alpha","userIds":["u-104","u-105"]}` + +Remediation: Pause payout eligibility and require identity review before reputation points affect bounty access. + +## WARN: BURST_ENDORSEMENT_RING +Several endorsements were created immediately after signup. + +Evidence: `{"count":4,"edges":["u-104->u-105","u-105->u-106","u-106->u-104","u-107->u-104"]}` + +Remediation: Delay endorsement credit until accounts age past the configured trust window. + +## WARN: HIGH_REPUTATION_DELTA_UNDER_RISK +The cluster gained enough reputation to affect rankings or bounty eligibility while risk signals are present. + +Evidence: `{"totalReputationDelta":119}` + +Remediation: Hold reputation deltas until the cluster review is resolved. + +## WARN: SUSPICIOUS_INVITATION_CHAIN +A non-seed account invited multiple high-velocity reputation accounts. + +Evidence: `{"inviter":"u-101","invitees":["u-104","u-105"]}` + +Remediation: Require manual review before granting invitation-derived reputation boosts. diff --git a/reputation-sybil-cluster-guard/requirements-map.md b/reputation-sybil-cluster-guard/requirements-map.md new file mode 100644 index 00000000..7a39922f --- /dev/null +++ b/reputation-sybil-cluster-guard/requirements-map.md @@ -0,0 +1,27 @@ +# Requirements Map + +Issue #15 describes a Community & User Reputation System with reputation, trust, rewards, and safeguards around user contributions. + +This contribution adds a distinct trust-and-safety control: sybil-cluster auditing before reputation affects rankings or bounty eligibility. + +| Issue capability | Implementation | +| --- | --- | +| Community reputation | Reviews reputation deltas and endorsement edges before points are trusted. | +| User trust safeguards | Detects shared payout handles, recycled device fingerprints, suspicious invitations, and review rings. | +| Reward/bounty eligibility | Emits a `quarantine-cluster` decision when reputation should not affect bounty access or payout eligibility. | +| Reviewer transparency | Generates JSON, Markdown, SVG, and MP4 artifacts from synthetic data. | +| Privacy-safe demo | Uses synthetic data only; no private user records, credentials, wallets, or social accounts. | + +## Non-Overlap + +This is not: + +- Probation reinstatement. +- Leaderboard eligibility or cohort privacy. +- Reputation review abuse. +- Identity impersonation. +- Badge renewal. +- Credit-ledger reputation. +- Completion reputation. + +It specifically focuses on clustered sybil signals that can inflate reputation before bounty eligibility or ranking decisions. diff --git a/reputation-sybil-cluster-guard/sample-data.js b/reputation-sybil-cluster-guard/sample-data.js new file mode 100644 index 00000000..282123f4 --- /dev/null +++ b/reputation-sybil-cluster-guard/sample-data.js @@ -0,0 +1,50 @@ +export const riskyReputationPacket = { + reviewWindow: "2026-06", + clusterId: "cluster-rho-17", + users: [ + { userId: "u-104", payoutHandle: "wallet-alpha", deviceFingerprint: "fp-77", invitedBy: "u-101", reputationDelta: 38 }, + { userId: "u-105", payoutHandle: "wallet-alpha", deviceFingerprint: "fp-77", invitedBy: "u-101", reputationDelta: 41 }, + { userId: "u-106", payoutHandle: "wallet-beta", deviceFingerprint: "fp-77", invitedBy: "u-105", reputationDelta: 36 }, + { userId: "u-107", payoutHandle: "wallet-gamma", deviceFingerprint: "fp-88", invitedBy: "u-106", reputationDelta: 4 }, + ], + endorsements: [ + { from: "u-104", to: "u-105", projectId: "bounty-1", createdMinutesAfterSignup: 9 }, + { from: "u-105", to: "u-106", projectId: "bounty-1", createdMinutesAfterSignup: 11 }, + { from: "u-106", to: "u-104", projectId: "bounty-2", createdMinutesAfterSignup: 13 }, + { from: "u-107", to: "u-104", projectId: "bounty-2", createdMinutesAfterSignup: 15 }, + ], + reviews: [ + { reviewer: "u-104", submitter: "u-105", projectId: "bounty-1", score: 5 }, + { reviewer: "u-105", submitter: "u-106", projectId: "bounty-1", score: 5 }, + { reviewer: "u-106", submitter: "u-104", projectId: "bounty-2", score: 5 }, + ], + controls: { + quarantineApplied: false, + manualReviewTicket: null, + leaderboardSuppressed: false, + payoutEligibilityPaused: false, + }, +}; + +export const cleanReputationPacket = { + reviewWindow: "2026-06", + clusterId: "cluster-eta-04", + users: [ + { userId: "u-201", payoutHandle: "wallet-201", deviceFingerprint: "fp-201", invitedBy: "seed", reputationDelta: 12 }, + { userId: "u-202", payoutHandle: "wallet-202", deviceFingerprint: "fp-202", invitedBy: "seed", reputationDelta: 9 }, + { userId: "u-203", payoutHandle: "wallet-203", deviceFingerprint: "fp-203", invitedBy: "u-201", reputationDelta: 6 }, + ], + endorsements: [ + { from: "u-201", to: "u-202", projectId: "bounty-7", createdMinutesAfterSignup: 1440 }, + { from: "u-202", to: "u-203", projectId: "bounty-8", createdMinutesAfterSignup: 2880 }, + ], + reviews: [ + { reviewer: "u-201", submitter: "u-203", projectId: "bounty-8", score: 4 }, + ], + controls: { + quarantineApplied: true, + manualReviewTicket: "REP-2048", + leaderboardSuppressed: true, + payoutEligibilityPaused: true, + }, +}; diff --git a/reputation-sybil-cluster-guard/test.js b/reputation-sybil-cluster-guard/test.js new file mode 100644 index 00000000..fc7bbd37 --- /dev/null +++ b/reputation-sybil-cluster-guard/test.js @@ -0,0 +1,22 @@ +import assert from "node:assert/strict"; +import { auditReputationSybilCluster, buildReviewerMarkdown, buildSummarySvg } from "./index.js"; +import { cleanReputationPacket, riskyReputationPacket } from "./sample-data.js"; + +const risky = auditReputationSybilCluster(riskyReputationPacket); +assert.equal(risky.decision, "quarantine-cluster"); +assert.ok(risky.riskScore >= 90); +assert.ok(risky.findings.some((finding) => finding.code === "SHARED_PAYOUT_HANDLE")); +assert.ok(risky.findings.some((finding) => finding.code === "RECYCLED_DEVICE_FINGERPRINT")); +assert.ok(risky.findings.some((finding) => finding.code === "SELF_REVIEW_RING_RISK")); +assert.ok(risky.findings.some((finding) => finding.code === "MISSING_CLUSTER_QUARANTINE")); + +const clean = auditReputationSybilCluster(cleanReputationPacket); +assert.equal(clean.decision, "reputation-clear"); +assert.equal(clean.riskScore, 0); +assert.equal(clean.summary.findingCount, 0); + +assert.throws(() => auditReputationSybilCluster(null), /reputation packet must be an object/); +assert.match(buildReviewerMarkdown(risky), /quarantine-cluster/); +assert.match(buildSummarySvg(risky), /Reputation Sybil Cluster Guard/); + +console.log("reputation sybil cluster guard tests passed");