Skip to content

Commit 28f7021

Browse files
committed
Add identity merge portability ledger
1 parent abb4798 commit 28f7021

11 files changed

Lines changed: 908 additions & 0 deletions

File tree

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
11
# deepevents.ai
22
deepevents.ai main codebase
3+
4+
- `identity-merge-portability-ledger/` adds identity merge conflict checks and profile export portability for user/project management workflows.
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# Identity Merge Portability Ledger
2+
3+
This module adds a focused user and project management slice for account merge and profile export workflows.
4+
5+
It covers:
6+
7+
- linked account conflict checks across ORCID, SAML, GitHub, Google, and email identities
8+
- merge decisions for duplicate researcher accounts
9+
- project owner, role, and object grant transfer actions after a merge
10+
- profile export packages with public/private profile handling
11+
- privacy redactions for risky third-party private exports
12+
- signed audit events and deterministic manifest digests
13+
14+
The implementation is dependency-free and uses synthetic sample data only.
15+
16+
## Run
17+
18+
```bash
19+
npm run check
20+
npm test
21+
npm run demo
22+
```
23+
24+
## Demo Assets
25+
26+
- `docs/demo.svg`
27+
- `docs/demo.gif`
28+
- `docs/demo.webm`
29+
30+
## API
31+
32+
```js
33+
import {
34+
evaluateIdentityPortability,
35+
renderIdentityPortabilityReport
36+
} from "./src/identity-merge-portability-ledger.js";
37+
38+
const result = evaluateIdentityPortability(input);
39+
console.log(renderIdentityPortabilityReport(result));
40+
```
Lines changed: 252 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,252 @@
1+
{
2+
"generatedAt": "2026-05-16T10:55:00.000Z",
3+
"policy": {
4+
"signingKey": "demo-signing-key",
5+
"verifiedEvidenceMinimum": 1
6+
},
7+
"accounts": [
8+
{
9+
"id": "acct-ada-main",
10+
"name": "Ada Rao",
11+
"email": "ada.rao@northbridge.edu",
12+
"orcid": "0000-0002-1825-0097",
13+
"institution": "Northbridge University",
14+
"samlSubject": "northbridge.edu:ada.rao",
15+
"github": "adarao-lab",
16+
"mfaEnabled": true,
17+
"privacyMode": "public",
18+
"linkedAccounts": [
19+
{
20+
"provider": "google",
21+
"subject": "ada.rao@northbridge.edu",
22+
"verified": true
23+
}
24+
],
25+
"profile": {
26+
"field": "Computational Biology",
27+
"bio": "Works on reproducible cell atlas pipelines.",
28+
"keywords": ["single-cell", "reproducibility", "atlas"],
29+
"affiliations": ["Northbridge Bioinformatics Lab"],
30+
"grants": ["NB-2025-CELL-42"],
31+
"publications": ["10.5555/cell-atlas-2025"],
32+
"activity": ["project-created:proj-cell-atlas", "review-completed:rev-884"]
33+
},
34+
"reputation": {
35+
"downloads": 1280,
36+
"forks": 34,
37+
"endorsements": 11,
38+
"reproducibilityScore": 96
39+
}
40+
},
41+
{
42+
"id": "acct-ada-old",
43+
"name": "Ada R.",
44+
"email": "ada.old@northbridge.edu",
45+
"institution": "Northbridge University",
46+
"mfaEnabled": true,
47+
"privacyMode": "private",
48+
"linkedAccounts": [
49+
{
50+
"provider": "orcid",
51+
"subject": "0000-0002-1825-0097",
52+
"verified": true
53+
},
54+
{
55+
"provider": "github",
56+
"subject": "adarao-archive",
57+
"verified": true
58+
}
59+
],
60+
"profile": {
61+
"field": "Computational Biology",
62+
"bio": "Legacy account imported from an old workspace.",
63+
"keywords": ["atlas"],
64+
"affiliations": ["Northbridge Bioinformatics Lab"],
65+
"grants": ["NB-2024-MIGRATE-7"],
66+
"publications": ["10.5555/legacy-atlas"],
67+
"activity": ["dataset-uploaded:ds-443"]
68+
},
69+
"reputation": {
70+
"downloads": 410,
71+
"forks": 8,
72+
"endorsements": 3,
73+
"reproducibilityScore": 89
74+
}
75+
},
76+
{
77+
"id": "acct-mira",
78+
"name": "Mira Chen",
79+
"email": "mira.chen@westlake.edu",
80+
"orcid": "0000-0003-1111-2222",
81+
"institution": "Westlake Institute",
82+
"samlSubject": "westlake.edu:mira.chen",
83+
"github": "mirachen",
84+
"mfaEnabled": false,
85+
"privacyMode": "private",
86+
"linkedAccounts": [
87+
{
88+
"provider": "github",
89+
"subject": "shared-lab-service",
90+
"verified": true
91+
}
92+
],
93+
"profile": {
94+
"field": "Neuroscience",
95+
"bio": "Reviews imaging datasets.",
96+
"keywords": ["imaging", "reviews"],
97+
"affiliations": ["Westlake Imaging Core"],
98+
"grants": ["WL-IRB-9"],
99+
"publications": ["10.5555/westlake-review"],
100+
"activity": ["review-requested:proj-cell-atlas"]
101+
},
102+
"reputation": {
103+
"downloads": 140,
104+
"forks": 2,
105+
"endorsements": 5,
106+
"reproducibilityScore": 72
107+
}
108+
},
109+
{
110+
"id": "acct-service",
111+
"name": "Shared Lab Service",
112+
"email": "service@northbridge.edu",
113+
"institution": "Northbridge University",
114+
"mfaEnabled": true,
115+
"privacyMode": "private",
116+
"linkedAccounts": [
117+
{
118+
"provider": "github",
119+
"subject": "shared-lab-service",
120+
"verified": true
121+
}
122+
],
123+
"profile": {
124+
"field": "Automation",
125+
"bio": "Machine account for legacy imports.",
126+
"keywords": ["automation"],
127+
"affiliations": ["Northbridge Platform Team"],
128+
"grants": [],
129+
"publications": [],
130+
"activity": []
131+
},
132+
"reputation": {
133+
"downloads": 0,
134+
"forks": 0,
135+
"endorsements": 0,
136+
"reproducibilityScore": 0
137+
}
138+
}
139+
],
140+
"projects": [
141+
{
142+
"id": "proj-cell-atlas",
143+
"title": "Cell Atlas Reproducibility Pack",
144+
"visibility": "institutional-only",
145+
"ownerId": "acct-ada-old",
146+
"roles": {
147+
"acct-ada-main": "admin",
148+
"acct-mira": "reviewer"
149+
},
150+
"objectGrants": [
151+
{
152+
"objectId": "dataset-raw-443",
153+
"type": "dataset",
154+
"accountId": "acct-ada-old",
155+
"permissions": ["read", "download"]
156+
},
157+
{
158+
"objectId": "notebook-qc-91",
159+
"type": "notebook",
160+
"accountId": "acct-ada-main",
161+
"permissions": ["read", "edit"]
162+
}
163+
]
164+
},
165+
{
166+
"id": "proj-imaging-review",
167+
"title": "Imaging Review Board",
168+
"visibility": "invitation-only",
169+
"ownerId": "acct-mira",
170+
"roles": {
171+
"acct-ada-main": "viewer"
172+
},
173+
"objectGrants": [
174+
{
175+
"objectId": "review-note-17",
176+
"type": "document",
177+
"accountId": "acct-mira",
178+
"permissions": ["read", "comment"]
179+
}
180+
]
181+
}
182+
],
183+
"mergeRequests": [
184+
{
185+
"id": "merge-ada-001",
186+
"primaryAccountId": "acct-ada-main",
187+
"duplicateAccountIds": ["acct-ada-old"],
188+
"requestedBy": "acct-ada-main",
189+
"reason": "same_researcher_legacy_import",
190+
"evidence": [
191+
{
192+
"provider": "orcid",
193+
"subject": "0000-0002-1825-0097",
194+
"verified": true,
195+
"confidence": 0.99
196+
},
197+
{
198+
"provider": "email",
199+
"subject": "ada.rao@northbridge.edu",
200+
"verified": true,
201+
"confidence": 0.95
202+
}
203+
]
204+
},
205+
{
206+
"id": "merge-mira-service-002",
207+
"primaryAccountId": "acct-mira",
208+
"duplicateAccountIds": ["acct-service"],
209+
"requestedBy": "acct-mira",
210+
"reason": "shared_github_cleanup",
211+
"evidence": [
212+
{
213+
"provider": "github",
214+
"subject": "shared-lab-service",
215+
"verified": true,
216+
"confidence": 0.71
217+
}
218+
]
219+
},
220+
{
221+
"id": "merge-missing-003",
222+
"primaryAccountId": "acct-ada-main",
223+
"duplicateAccountIds": ["acct-ghost"],
224+
"requestedBy": "acct-ada-main",
225+
"reason": "manual_cleanup",
226+
"evidence": []
227+
}
228+
],
229+
"profileExports": [
230+
{
231+
"id": "export-ada-full",
232+
"accountId": "acct-ada-main",
233+
"requestedBy": "acct-ada-main",
234+
"includePrivate": true,
235+
"format": "json"
236+
},
237+
{
238+
"id": "export-mira-third-party",
239+
"accountId": "acct-mira",
240+
"requestedBy": "acct-ada-main",
241+
"includePrivate": true,
242+
"format": "json"
243+
},
244+
{
245+
"id": "export-service-public",
246+
"accountId": "acct-service",
247+
"requestedBy": "acct-service",
248+
"includePrivate": false,
249+
"format": "json"
250+
}
251+
]
252+
}
84.7 KB
Loading
Lines changed: 49 additions & 0 deletions
Loading
36.5 KB
Binary file not shown.
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# Requirement Map
2+
3+
## Authentication & Identity
4+
5+
- Account linking is modeled through verified ORCID, SAML, GitHub, Google, and email subjects.
6+
- Merge decisions detect verified identity conflicts before accounts are collapsed.
7+
- MFA state is enforced when a researcher requests private profile export data.
8+
9+
## Researcher Profiles
10+
11+
- Export packages include public profile fields, keywords, reputation metrics, linked identities, and project memberships.
12+
- Private fields such as email, grants, affiliations, publications, and activity are included only when policy allows it.
13+
- Redactions make public vs private profile behavior reviewable.
14+
15+
## Project Spaces
16+
17+
- Merge decisions inspect project ownership, roles, and object grants.
18+
- Duplicate-account ownership and object grants are converted into explicit transfer actions.
19+
- Export packages include project visibility, role, and object grant counts.
20+
21+
## Permissions & Access Control
22+
23+
- Third-party private export requests are held for review.
24+
- Missing accounts and identity-provider collisions block unsafe merges.
25+
- Project and object-level access changes are recorded as actions instead of hidden side effects.
26+
27+
## Audit Log
28+
29+
- Merge and export decisions emit signed audit events.
30+
- The manifest digest is deterministic so reviewers can compare reruns.
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"name": "identity-merge-portability-ledger",
3+
"version": "1.0.0",
4+
"description": "Identity merge and profile portability guard for research workspaces.",
5+
"type": "module",
6+
"scripts": {
7+
"check": "node --check src/identity-merge-portability-ledger.js && node --check scripts/demo.js && node --check test/identity-merge-portability-ledger.test.js",
8+
"test": "node --test test/*.test.js",
9+
"demo": "node scripts/demo.js"
10+
},
11+
"keywords": [
12+
"identity",
13+
"profile-portability",
14+
"workspace-governance"
15+
],
16+
"license": "MIT"
17+
}

0 commit comments

Comments
 (0)