196 lines
5.9 KiB
TypeScript
196 lines
5.9 KiB
TypeScript
/**
|
||
* rCred — Contribution Recognition via CredRank.
|
||
*
|
||
* Types + DocSchema definitions for contribution graphs, cred scores,
|
||
* and grain distribution config.
|
||
*
|
||
* Doc IDs:
|
||
* {space}:rcred:graph → ContribGraphDoc
|
||
* {space}:rcred:scores → CredScoresDoc
|
||
* {space}:rcred:config → CredConfigDoc
|
||
*/
|
||
|
||
import type { DocSchema } from '../../shared/module';
|
||
|
||
// ── Graph types ──
|
||
|
||
export type CredNodeType = 'contributor' | 'contribution';
|
||
export type CredEdgeType = 'authored' | 'commented-on' | 'reacted-to' | 'attended' | 'voted-on' | 'completed';
|
||
|
||
export interface CredNode {
|
||
id: string;
|
||
type: CredNodeType;
|
||
/** DID for contributor nodes */
|
||
did?: string;
|
||
label: string;
|
||
sourceModule: string;
|
||
contributionType: string;
|
||
timestamp: number;
|
||
weight: number;
|
||
}
|
||
|
||
export interface CredEdge {
|
||
id: string;
|
||
from: string;
|
||
to: string;
|
||
type: CredEdgeType;
|
||
weight: number;
|
||
}
|
||
|
||
export interface ContribGraphDoc {
|
||
meta: {
|
||
module: string;
|
||
collection: string;
|
||
version: number;
|
||
spaceSlug: string;
|
||
createdAt: number;
|
||
};
|
||
nodes: Record<string, CredNode>;
|
||
edges: Record<string, CredEdge>;
|
||
lastBuiltAt: number;
|
||
stats: {
|
||
nodeCount: number;
|
||
edgeCount: number;
|
||
contributorCount: number;
|
||
contributionCount: number;
|
||
};
|
||
}
|
||
|
||
// ── Score types ──
|
||
|
||
export interface CredScore {
|
||
did: string;
|
||
label: string;
|
||
cred: number;
|
||
rawScore: number;
|
||
grainLifetime: number;
|
||
epochScores: Record<string, number>;
|
||
/** Module → cred contribution */
|
||
breakdown: Record<string, number>;
|
||
lastActive: number;
|
||
}
|
||
|
||
export interface CredScoresDoc {
|
||
meta: {
|
||
module: string;
|
||
collection: string;
|
||
version: number;
|
||
spaceSlug: string;
|
||
createdAt: number;
|
||
};
|
||
scores: Record<string, CredScore>;
|
||
totalCred: number;
|
||
computedAt: number;
|
||
epochId: string;
|
||
}
|
||
|
||
// ── Config types ──
|
||
|
||
export interface ContributionTypeWeight {
|
||
type: string;
|
||
weight: number;
|
||
description: string;
|
||
}
|
||
|
||
export interface CredConfigDoc {
|
||
meta: {
|
||
module: string;
|
||
collection: string;
|
||
version: number;
|
||
spaceSlug: string;
|
||
createdAt: number;
|
||
};
|
||
weights: Record<string, ContributionTypeWeight>;
|
||
grainPerEpoch: number;
|
||
epochLengthDays: number;
|
||
/** Fraction of grain allocated to lifetime equity (0-1) */
|
||
slowFraction: number;
|
||
/** Fraction of grain allocated to current epoch (0-1) */
|
||
fastFraction: number;
|
||
/** PageRank damping factor (α in teleportation probability) */
|
||
dampingFactor: number;
|
||
lookbackDays: number;
|
||
enabled: boolean;
|
||
lastEpochAt: number;
|
||
grainTokenId: string;
|
||
}
|
||
|
||
// ── Default contribution weights ──
|
||
|
||
export const DEFAULT_WEIGHTS: Record<string, ContributionTypeWeight> = {
|
||
'task-created': { type: 'task-created', weight: 1.0, description: 'Created a task' },
|
||
'task-completed': { type: 'task-completed', weight: 3.0, description: 'Completed a task' },
|
||
'doc-authored': { type: 'doc-authored', weight: 2.0, description: 'Authored a document' },
|
||
'comment-authored': { type: 'comment-authored', weight: 1.0, description: 'Wrote a comment' },
|
||
'message-sent': { type: 'message-sent', weight: 0.5, description: 'Sent a chat message' },
|
||
'reaction-given': { type: 'reaction-given', weight: 0.2, description: 'Reacted to a message' },
|
||
'event-scheduled': { type: 'event-scheduled', weight: 2.0, description: 'Scheduled an event' },
|
||
'event-attended': { type: 'event-attended', weight: 1.5, description: 'Attended an event' },
|
||
'proposal-authored': { type: 'proposal-authored', weight: 3.0, description: 'Authored a proposal' },
|
||
'vote-cast': { type: 'vote-cast', weight: 1.0, description: 'Cast a vote' },
|
||
'flow-created': { type: 'flow-created', weight: 2.0, description: 'Created a flow' },
|
||
'budget-allocated': { type: 'budget-allocated', weight: 1.5, description: 'Allocated budget' },
|
||
'commitment-created': { type: 'commitment-created', weight: 2.0, description: 'Created a time commitment' },
|
||
'settlement-completed': { type: 'settlement-completed', weight: 4.0, description: 'Settled a time commitment' },
|
||
'address-added': { type: 'address-added', weight: 1.0, description: 'Added a wallet address' },
|
||
'tx-annotated': { type: 'tx-annotated', weight: 0.5, description: 'Annotated a transaction' },
|
||
};
|
||
|
||
// ── Doc ID helpers ──
|
||
|
||
export function graphDocId(space: string) {
|
||
return `${space}:rcred:graph` as const;
|
||
}
|
||
|
||
export function scoresDocId(space: string) {
|
||
return `${space}:rcred:scores` as const;
|
||
}
|
||
|
||
export function configDocId(space: string) {
|
||
return `${space}:rcred:config` as const;
|
||
}
|
||
|
||
// ── DocSchema definitions (for module registration) ──
|
||
|
||
export const graphSchema: DocSchema<ContribGraphDoc> = {
|
||
pattern: '{space}:rcred:graph',
|
||
description: 'Contribution graph — nodes and edges from all module activity',
|
||
init: (): ContribGraphDoc => ({
|
||
meta: { module: 'rcred', collection: 'graph', version: 1, spaceSlug: '', createdAt: Date.now() },
|
||
nodes: {},
|
||
edges: {},
|
||
lastBuiltAt: 0,
|
||
stats: { nodeCount: 0, edgeCount: 0, contributorCount: 0, contributionCount: 0 },
|
||
}),
|
||
};
|
||
|
||
export const scoresSchema: DocSchema<CredScoresDoc> = {
|
||
pattern: '{space}:rcred:scores',
|
||
description: 'CredRank scores — per-contributor cred and grain tallies',
|
||
init: (): CredScoresDoc => ({
|
||
meta: { module: 'rcred', collection: 'scores', version: 1, spaceSlug: '', createdAt: Date.now() },
|
||
scores: {},
|
||
totalCred: 0,
|
||
computedAt: 0,
|
||
epochId: '',
|
||
}),
|
||
};
|
||
|
||
export const configSchema: DocSchema<CredConfigDoc> = {
|
||
pattern: '{space}:rcred:config',
|
||
description: 'CredRank configuration — contribution weights and grain parameters',
|
||
init: (): CredConfigDoc => ({
|
||
meta: { module: 'rcred', collection: 'config', version: 1, spaceSlug: '', createdAt: Date.now() },
|
||
weights: { ...DEFAULT_WEIGHTS },
|
||
grainPerEpoch: 1000,
|
||
epochLengthDays: 7,
|
||
slowFraction: 0.8,
|
||
fastFraction: 0.2,
|
||
dampingFactor: 0.15,
|
||
lookbackDays: 90,
|
||
enabled: true,
|
||
lastEpochAt: 0,
|
||
grainTokenId: '',
|
||
}),
|
||
};
|