feat(identity): separate opt-in for reviewer / juror / expert pools (issue #107)#115
Open
vrkothekar wants to merge 5 commits into
Open
feat(identity): separate opt-in for reviewer / juror / expert pools (issue #107)#115vrkothekar wants to merge 5 commits into
vrkothekar wants to merge 5 commits into
Conversation
Adds a banner near the top of the README pointing to the published Whitepaper at theailab.org/whitepaper, and updates the Links table with the canonical Whitepaper URL, the PDF download URL, and the errata channel. Also corrects the Protocol Spec link to v5.0. The Whitepaper is the canonical public specification of the TIP Protocol. The Protocol Spec (CTID v5.0) remains the technical reference for endpoint contracts and message formats. License: Whitepaper is CC BY 4.0. Implementations remain under TIPCL-1.0 with conversion to Apache 2.0 on Jan 1, 2031.
…inks table
The TIP Protocol Whitepaper, Version 1.0 is now permanently archived
on Zenodo (operated by CERN) with a citable DOI. This README update
surfaces the DOI as a discoverable badge at the top of the page,
adds the author's ORCID iD alongside the Wikidata QID, and adds
three rows to the Links table for the Version DOI, the Concept
DOI, and the Zenodo record URL.
The full citation in the README banner now uses the canonical
Zenodo title ("Trust Identity Protocol (TIP): An Open Standard for
Verified Human Identity and Content Provenance on the Internet")
and ends with the DOI URL, so anyone clicking the citation can
resolve to the permanent record.
The DOI badge surfaces in the GitHub repository preview and in any
README mirror.
…ORUM refund + idle-verdict fallback Fixes Issue #106. Three scoring bugs + one infrastructure stall: Bug 1 — REVIEWER_WRONG_DISMISS_CLAWBACK not fired at Stage-2 UPHELD When a jury upheld a dispute after the prescan reviewer dismissed the content, the reviewer's +5 correct-dismiss bonus was never reversed. Added clawback (delta = reviewer_wrong_dismiss_clawback = -5) in jury.js after the ADJUDICATION_RESULT tx is built, guarded by !escalatedReview to keep it mutually exclusive from the CONFIRM-bonus path. Stage-3 overturn (UPHELD→DISMISSED) reverses the clawback (+5 again). NO_QUORUM→Stage-3 UPHELD fires a distinct clawback with reason suffix _no_quorum. Bug 2 — reviewer.min_score was 800, should be 600 genesis.js: min_score 800 → 600; protocol-constants.js + python genesis.py updated. Re-signed genesis (resign-genesis.js) to keep GENESIS_TX_SIGNATURE valid. Bug 3 — terminal NO_QUORUM gave disputer no stake refund When canEscalate=false and Stage-3 is unavailable, jury.js now pushes a SCORE_UPDATE of delta=+DISPUTE.DISPUTER_STAKE for the disputer before returning the NO_QUORUM terminal verdict. Infrastructure — verdict trigger stalls on idle clusters Bullshark guards onOrderedTxs with `if (orderedTxs.length > 0)`, so checkPending is never called when there's no mempool traffic. Added a 3-second setInterval fallback in consensus/index.js that calls checkPending(Date.now(), currentRound()) when verdictTrigger.size() > 0. Safe: existing leader-gate (round-modulo) and ADJUDICATION_RESULT first-wins idempotency prevent double- fire. Cleared in stop(). Tests: 57 new tests across dispute-stake-economy.test.js (+137 lines) and reviewer-payment.test.js (+342 lines) covering all 5 verdict paths. 197/209 scoring tests pass (12 pre-existing skips, no regressions). Live-tested on 5-node Docker cluster: reviewer 951→956→951 (net 0). ✓
…issue #107) Splits the single `reviewer_consent` field into three independent consent fields — `reviewer_consent` (pre-scan review), `juror_consent` (Stage-2 jury), and `expert_consent` (Stage-3 expert panel) — so users can opt into any combination of adjudication roles. Back-compat: new columns are DEFAULT NULL. Read paths in `_parseIdentityRow` (SQLite) and `_hydrate` (knex-adapter) fall back to `reviewer_consent` for pre-migration rows, preserving existing opt-ins without a re-save. Jury.js gates use the same `?? reviewer_consent` pattern. `_canonIdentity` applies identical fallback so all 5 nodes produce the same Merkle root. Also fixes a `Date.now()` call in `consensus/index.js` (introduced in the #106 idle-verdict-fallback timer) that violated the timestamp-discipline rule; replaced with `nowMs()` from shared/time. Changes: - schemas/update-profile.js: add juror_consent + expert_consent to KNOWN_FIELDS; extend org gate to cover all three consent fields - dag.js: _canonIdentity, SQLite schema, saveIdentity, _parseIdentityRow - knex-adapter.js: createTable, saveIdentity, _hydrate back-compat - jury.js: selectJury → juror_consent gate; selectExperts → expert_consent - profile-service.js: becomeJuror/stopJuror/becomeExpert/stopExpert helpers - routes/identity.js: /become-juror, /stop-juror, /become-expert, /stop-expert - Tests: jury-consent.test.js (5 new cases), profile-service-reviewer.test.js (6 new cases), update-profile.test.js (4 new integration cases) - consensus/index.js: Date.now() → nowMs() fix
…ripts - inject-prescan-review.js: backdate prescan_completed_at (not just registered_at) — trigger uses prescan_completed_at as its 48 h anchor; add --ignore-empty-pool flag since selectReviewer has Pass-2/3 fallbacks - seed-jurors.js: DEV-ONLY script to register temp-user key files as juror-eligible personal identities (mocked ZK proof, ZK_SKIP_VERIFY=true required on nodes); enables juror_consent + SQL-bumps scores to 750 - check-nodes.sh: quick one-shot health check — state-root agreement, anti-entropy counters, byzantine-fork halt status, peer connectivity
01aaeef to
0b424f2
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Closes #107. Splits the single
reviewer_consenttoggle into three independent opt-in fields so identities can choose adjudication roles separately:reviewer_consent— pre-scan reviewer (1 reviewer per flagged content, 48 h async)juror_consent— Stage-2 jury panel (7-seat commit-reveal, time-boxed)expert_consent— Stage-3 expert appeal panel (highest score bar, highest accountability)Previously, opting into any adjudication role opted you into all three. This caused reviewers to be drafted onto jury panels they hadn't consented to, and experts to be pulled from a pool that included identities who only wanted to be reviewers.
Changes
Protocol / schema
UPDATE_PROFILEschema: addedjuror_consentandexpert_consentas sparse-update fields;reviewer_consentretained for back-compat (existing opted-in identities remain eligible via fallback injury.jsandreviewer-selection.js)dag.js/knex-adapter.js: new columns wired through_canonIdentity,saveIdentity,_hydratejury.js:selectJurynow filters onjuror_consent(fallback toreviewer_consentfor pre-split identities);selectExpertsfilters onexpert_consent(same fallback)genesis.js/protocol-constants.js: updated genesis defaults and constant accessorsRoutes / services
POST /v1/identity/:tipId/become-jurorandPOST /v1/identity/:tipId/become-expertFrontend
settings.html: three independent toggle switches replacing the single "Become a reviewer" toggle; each signs its ownUPDATE_PROFILEtxTimestamp discipline
Date.now()usage inconsensus/index.jsfallback timer →nowMs()fromshared/time(enforced bytimestamp-discipline.test.js)Dev tooling
scripts/inject-prescan-review.js: fixed to backdateprescan_completed_at(trigger anchor) not justregistered_at; added--ignore-empty-poolfor Pass-3 fallback testingscripts/seed-jurors.js: DEV-ONLY — registers temp-user key files as juror-eligible identities (mocked ZK proof, requiresZK_SKIP_VERIFY=true)scripts/check-nodes.sh: one-shot cluster health check (state-root agreement, halt status, peer connectivity)Tests
update-profile.test.js: juror/expert consent fields accepted and rejected correctlyjury-consent.test.js:selectJury/selectExpertsfilter by new fields; back-compat fallback for pre-split identitiesprofile-service-reviewer.test.js:becomeJuror/becomeExpertconvenience methodsdispute-stake-economy.test.js,reviewer-payment.test.js: scoring path coverageLocal test plan (verified)
POST /v1/identity/:tipId/become-reviewer/become-juror/become-expertall accept and reject correctlyorganization_ineligible)juror_consent=truepool → UPHELD verdict viadrive-jury.jstimestamp-disciplineregression test passes (0Date.now()outsideshared/time)