Files
bitgate/packages/core/src/index.js
T
thePR0M3TH3AN 4f689184e2 feat(core): rebuild governance core to the plan's decision model
The evaluator was a skeleton with invented thresholds (5/3/10/5) and two
unimplemented branches. Rebuild it against the migration plan's spec and the
behavior characterized from the pinned reference commit.

Core:
- four independent decision dimensions (ranking, visibility, interaction,
  transaction) with severity ladders and max-merge composition
- stable reason identifiers replacing free-text strings
- structured evidence, redacted unless a profile opts in
- administrative-state reduction with capability filtering at merge time, so
  revoking a role drops that actor's entries immediately
- protected actors stripped from every denial set
- snapshot fingerprints for cache invalidation
- generic policy engine: applications supply profiles and category thresholds;
  the core carries none of its own

Characterization:
- 34 generated fixtures covering every behavior the plan's Phase 0 requires
- conformance suite that actually evaluates them, replacing a placeholder that
  asserted a list's length
- reference thresholds (3/3/20/5, 60-day mute window) live in bitvid-compat as
  an application profile, not as engine defaults

Fixes found while building:
- reduceAdminState accepted malformed target identifiers, because getTargetKey
  formats anything it is given
- community-user-deny fired for any contributor rather than only for
  community-curated sources

273 tests pass; typecheck and the reference-import guard are clean.
2026-08-09 17:33:41 -04:00

119 lines
3.1 KiB
JavaScript

// @nostr-governance/core
//
// Pure, headless governance primitives. No I/O, no browser globals, no
// application thresholds. Applications supply a policy definition and a
// snapshot; the evaluator returns a decision they apply.
export {
normalizePubkey,
normalizeEventId,
normalizeAddress,
createUserTarget,
createEventTarget,
getTargetKey,
} from "./identifiers.js";
export {
areTargetsEqual,
isValidTarget,
createTarget,
getParentTarget,
isDescendantOf,
} from "./targets.js";
export {
GOVERNANCE_CAPABILITIES,
DEFAULT_ROLE_CAPABILITIES,
isGovernanceCapability,
createAuthorityState,
getActorRoles,
getActorCapabilities,
hasCapability,
hasRole,
isProtectedActor,
createRoleDefinition,
} from "./authority.js";
export {
createEmptyAdminState,
reduceAdminState,
protectActors,
mergeCommunitySource,
isDenied,
serializeAdminState,
} from "./adminState.js";
export {
REASON_IDS,
isReasonId,
createReason,
dedupeReasons,
} from "./reasons.js";
export {
createEmptyEvidence,
freezeEvidence,
redactEvidence,
} from "./evidence.js";
export {
RANKING_LADDER,
VISIBILITY_LADDER,
INTERACTION_LADDER,
TRANSACTION_LADDER,
NEUTRAL_POLICY,
effectSeverity,
maxEffect,
createNeutralDecision,
normalizeDimensionEffects,
normalizeCategoryThresholds,
normalizePolicyProfile,
normalizePolicyDefinition,
createPolicyDefinition,
resolveProfile,
resolveThresholds,
applyThresholds,
applyEffects,
composeDecisions,
} from "./policy.js";
export {
canonicalStringify,
hashString,
fingerprint,
snapshotFingerprint,
} from "./fingerprint.js";
export {
evaluateTarget,
evaluateMany,
createSnapshot,
createViewerState,
resolveTrustSet,
aggregateReports,
aggregateMutes,
} from "./evaluator.js";
/**
* @typedef {import('./identifiers.js').GovernanceTarget} GovernanceTarget
* @typedef {import('./identifiers.js').UserTarget} UserTarget
* @typedef {import('./identifiers.js').EventTarget} EventTarget
* @typedef {import('./identifiers.js').AddressTarget} AddressTarget
* @typedef {import('./authority.js').AuthorityState} AuthorityState
* @typedef {import('./authority.js').GovernanceCapability} GovernanceCapability
* @typedef {import('./adminState.js').AdminState} AdminState
* @typedef {import('./adminState.js').Contribution} Contribution
* @typedef {import('./policy.js').PolicyDefinition} PolicyDefinition
* @typedef {import('./policy.js').PolicyProfile} PolicyProfile
* @typedef {import('./policy.js').PolicyContext} PolicyContext
* @typedef {import('./policy.js').GovernanceDecision} GovernanceDecision
* @typedef {import('./policy.js').CategoryThresholds} CategoryThresholds
* @typedef {import('./evidence.js').GovernanceEvidence} GovernanceEvidence
* @typedef {import('./reasons.js').GovernanceReason} GovernanceReason
* @typedef {import('./reasons.js').ReasonId} ReasonId
* @typedef {import('./evaluator.js').GovernanceSnapshot} GovernanceSnapshot
* @typedef {import('./evaluator.js').ViewerState} ViewerState
* @typedef {import('./evaluator.js').ReportRecord} ReportRecord
* @typedef {import('./evaluator.js').MuteRecord} MuteRecord
*/