Themis is implemented as 40 TypeScript library packages under libs/themis/.
This document is the ground-truth reference for engineers working inside the
domain: it lists every package, defines every core data model and schema, and
specifies the event catalogue, graph module, database schema, voting mechanisms,
originality-shield protocol, dispute-routing logic, and academic-integrity
adjudication engine.
A new engineer should read this document alongside architecture.md (which
explains why the pieces fit together the way they do) and features.md (which
describes each capability in plain language). This document answers exactly
what each module contains and how the types are shaped.
1. Library Inventory#
Themis is a library-only domain. There are no apps/themis/ or
services/themis/ directories. All code lives under libs/themis/, which
contains 40 library packages. Every package declares version: 0.1.0 in its
package.json and is named under the @themis/ scope.
1.1 Foundation and full governance libraries#
The 33 packages below form the core governance platform. Each is tagged with a
tier that indicates its position in the dependency graph: themis:tier:core for
the single foundation package and themis:tier:domain for all others.
| Package | Path | Tier tag |
|---|---|---|
@themis/core |
libs/themis/core |
themis:tier:core |
@themis/voting |
libs/themis/voting |
themis:tier:domain |
@themis/deliberation |
libs/themis/deliberation |
themis:tier:domain |
@themis/decisions |
libs/themis/decisions |
themis:tier:domain |
@themis/reputation |
libs/themis/reputation |
themis:tier:domain |
@themis/identity |
libs/themis/identity |
themis:tier:domain |
@themis/accountability |
libs/themis/accountability |
themis:tier:domain |
@themis/transparency |
libs/themis/transparency |
themis:tier:domain |
@themis/privacy |
libs/themis/privacy |
themis:tier:domain |
@themis/constitutions |
libs/themis/constitutions |
themis:tier:domain |
@themis/dao |
libs/themis/dao |
themis:tier:domain |
@themis/corporate |
libs/themis/corporate |
themis:tier:domain |
@themis/nonprofit |
libs/themis/nonprofit |
themis:tier:domain |
@themis/community |
libs/themis/community |
themis:tier:domain |
@themis/civic |
libs/themis/civic |
themis:tier:domain |
@themis/traditional |
libs/themis/traditional |
themis:tier:domain |
@themis/digital |
libs/themis/digital |
themis:tier:domain |
@themis/international |
libs/themis/international |
themis:tier:domain |
@themis/justice |
libs/themis/justice |
themis:tier:domain |
@themis/arbitration |
libs/themis/arbitration |
themis:tier:domain |
@themis/sectors |
libs/themis/sectors |
themis:tier:domain |
@themis/treasury |
libs/themis/treasury |
themis:tier:domain |
@themis/funding |
libs/themis/funding |
themis:tier:domain |
@themis/environmental |
libs/themis/environmental |
themis:tier:domain |
@themis/crisis |
libs/themis/crisis |
themis:tier:domain |
@themis/policy |
libs/themis/policy |
themis:tier:domain |
@themis/analytics |
libs/themis/analytics |
themis:tier:domain |
@themis/knowledge |
libs/themis/knowledge |
themis:tier:domain |
@themis/frameworks |
libs/themis/frameworks |
themis:tier:domain |
@themis/simulation |
libs/themis/simulation |
themis:tier:domain |
@themis/ai |
libs/themis/ai |
themis:tier:domain |
@themis/integrations |
libs/themis/integrations |
themis:tier:domain |
@themis/academic-integrity |
libs/themis/academic-integrity |
themis:tier:domain |
1.2 Dispute-resolution routing library#
@themis/dispute-resolution is tagged separately because it depends on
@concordia/contracts rather than @themis/core, and because it was introduced
as a discrete phase of work (Phase 179). It is a sibling to
@themis/arbitration, not a layer above it.
| Package | Path | Tags |
|---|---|---|
@themis/dispute-resolution |
libs/themis/dispute-resolution |
scope:themis, layer:domain, type:lib, phase:179 |
@themis/dispute-resolution is distinct from @themis/arbitration.
@themis/arbitration implements decentralized arbitration, dispute management,
and mediation engines (≈5,700 LOC of source). @themis/dispute-resolution is a
small (≈790 LOC) routing/intake layer that classifies a dispute and decides
whether to route it into the Concordia mediation substrate; it also implements
the V2 DSA Statement-of-Reasons and moderation/tournament dispute flows.
1.3 Originality / IP-protection libraries#
The six originality-shield libraries also depend on @concordia/contracts
rather than @themis/core. They are intentionally thin: all verdict computation
is delegated to the Concordia contract, so that the detection logic lives in one
place and can be updated without touching six separate libraries.
There are six originality-shield libraries plus one shared core. They are
real but thin: the five media shields are each ≈50 LOC wrappers that delegate
all evaluation logic to @themis/originality-shields, which in turn delegates
to the @concordia/contracts originality-shield contract.
| Package | Path | Source size | Tags |
|---|---|---|---|
@themis/originality-shields |
libs/themis/originality-shields |
≈365 LOC | scope:themis, layer:domain, type:lib, domain:originality |
@themis/music-shield |
libs/themis/music-shield |
≈47 LOC | scope:themis, layer:domain, type:lib, domain:originality |
@themis/visual-shield |
libs/themis/visual-shield |
≈57 LOC | scope:themis, layer:domain, type:lib, domain:originality |
@themis/text-shield |
libs/themis/text-shield |
≈47 LOC | scope:themis, layer:domain, type:lib, domain:originality |
@themis/video-shield |
libs/themis/video-shield |
≈47 LOC | scope:themis, layer:domain, type:lib, domain:originality |
@themis/design-shield |
libs/themis/design-shield |
≈49 LOC | scope:themis, layer:domain, type:lib, domain:originality |
There is no model-shield, character-shield, game-shield, or
animation-shield package, and no @themis/likeness package, in the
codebase. See §7 for the shield specification, §11 for the forthcoming
@themis/likeness NIL / likeness ledger, and §16 for the planned-work notes.
1.4 Forthcoming Themis-owned libraries#
One Themis-owned library is specified but not yet built. It is listed here for
traceability and is described in full in §11; it is not present in
libs/themis/ today and nothing in the rest of this document should be read as
describing existing code for it.
| Package | Path | Status |
|---|---|---|
@themis/likeness (forthcoming, not yet implemented) |
libs/themis/likeness/ |
Specified in §11; reciprocal task tracker in §11.8 |
2. Technology Stack#
The table below lists every tool and runtime used across the domain. Note that
the originality shields use tsup instead of the standard @nx/js:tsc executor
because they require a slightly different build pipeline.
| Component | Technology |
|---|---|
| Language | TypeScript (ESM, strict mode) |
| Runtime | Node.js (engines.node >= 20) |
| Build | Nx @nx/js:tsc (most libraries); nx:run-commands + tsup for the originality shields |
| Testing | Vitest (per-library configs, shared vitest.shared.ts) |
| Database | PostgreSQL (schema and migrations from @themis/core) |
| Validation | Zod (@themis/core types are Zod schemas; many libraries use Zod) |
| Event transport | Kafka publisher abstraction in @themis/core (with an in-memory implementation) |
| Shared config | Domain-wide tsconfig.domain.json, eslint.config.js, prettier.config.js under libs/themis/ |
3. Core Data Models (@themis/core)#
@themis/core source is organized into four module groups: types/, events/,
graph/, and database/. All public symbols are re-exported from
libs/themis/core/src/index.ts. The core types are Zod schemas; each schema has
a matching inferred TypeScript type and parse* / safeParse* helpers. The
interfaces below are the inferred shapes — the Zod schemas are the authoritative
runtime definitions, and these TypeScript interfaces should be understood as
their structural projections.
3.1 Organization#
Defined in types/organization.ts. An Organization is the top-level aggregate
— it contains the charter, governs members and roles, and is the anchor for all
events in the audit log.
interface Organization {
name: string; // 1–255 chars
jurisdiction: Jurisdiction;
type: OrganizationType;
charter: Charter;
foundingDate: string; // YYYY-MM-DD
status: OrganizationStatus;
}
OrganizationType (ORGANIZATION_TYPE_VALUES) enumerates the 15 recognized
organizational forms. Every Themis governance library is designed to work with
at least one of these types:
DAO, Corporation, LLC, NonProfit, Cooperative, Association, Union,
Foundation, Municipality, Legislature, PoliticalParty, SportsClub,
CommunityOrg, NetworkState, HybridEntity.
OrganizationStatus (ORGANIZATION_STATUS_VALUES) tracks the lifecycle of an
organization itself: forming, active, suspended, dissolved, merged.
Jurisdiction captures where the organization is legally anchored: country
(2-letter ISO code, upper-cased), optional stateProvince, legalFramework,
regulatoryBody.
3.2 Charter#
A Charter is the organization's constitutional document. It is embedded inside
the Organization rather than being a separate top-level entity, because a
charter is meaningless without the organization it governs.
interface Charter {
preamble: string;
articles: CharterArticle[]; // ≥1; { articleNumber, title, body }
bylaws: CharterBylaw[]; // ≥1; { section, title, body }
amendments: CharterAmendment[]; // { amendmentNumber, title, summary, effectiveDate }
effectiveDate: string; // YYYY-MM-DD
ratification: CharterRatification;
}
interface CharterRatification {
status: RatificationStatus; // pending | ratified | rejected
ratifiedBy: string[]; // ≥1
ratificationDate: string; // YYYY-MM-DD
method: string;
}
3.3 Member, Role, GovernanceIdentity, Delegation#
Defined in types/member-role.ts. These four types together describe who
participates in governance and how their participation is structured. UUIDs
are validated against UUID_REGEX (v1–v5 UUID form).
interface Member {
id: string; // UUID
identity: GovernanceIdentity;
organizationId: string; // UUID
roles: Role[];
reputationScore: number;
delegationStatus: DelegationStatus;
votingPower: number; // ≥0
joinDate: string; // YYYY-MM-DD
status: MemberStatus;
}
interface GovernanceIdentity {
did: string;
verifiableCredentials: VerifiableCredential[];
sybilScore: number; // 0–1
eligibilityProofs: EligibilityProof[];
}
interface Role {
name: string;
permissions: Permission[]; // ≥1
responsibilities: string[]; // ≥1
term: RoleTerm; // { startDate, endDate?, renewable }
electionMethod: ElectionMethod;
}
interface Delegation {
delegator: string; // UUID
delegate: string; // UUID
scope: Record<string, unknown>;
weight: number; // >0
expiry: string | null; // ISO datetime
revocable: boolean;
}
The following enums define the valid values for fields on these types:
Permission(PERMISSION_VALUES) —Propose,Vote,Delegate,Execute,Veto,Amend,Moderate,Audit,AdministerTreasury,ManageMembers,ConfigureGovernance.MemberStatus(MEMBER_STATUS_VALUES) —invited,active,inactive,suspended,removed.DelegationStatus(DELEGATION_STATUS_VALUES) —none,delegating,receiving,both,revoked.ElectionMethod(ELECTION_METHOD_VALUES) —elected,appointed,sortition,rotating,consensus.
VerifiableCredential carries: credentialId, credentialType, issuer,
issuedAt, optional expiresAt, claims.
EligibilityProof carries: proofType, proofValue, optional verifiedBy,
verifiedAt, metadata.
3.4 Proposal and Vote#
Defined in types/proposal-vote.ts. The Proposal, Vote, and VotingResult
types are the core of any active governance process. A proposal moves through a
sequence of statuses; each status transition is recorded as an event in the
audit log.
interface Proposal {
id: string; // UUID
organization: string; // UUID
author: string; // UUID
title: string; // 1–255 chars
body: string;
type: ProposalType;
status: ProposalStatus;
createdAt: string; // ISO datetime
discussionEnd: string | null;
votingStart: string | null;
votingEnd: string | null;
executionTime: string | null;
quorumRequired: number; // 0–1
thresholdRequired: number; // 0–1
executionPayload: Record<string, unknown>;
}
interface Vote {
voter: string; // UUID
proposal: string; // UUID
choice: VoteChoice;
weight: number; // >0
timestamp: string; // ISO datetime
proof: Record<string, unknown>; // default {}
delegationChain: string[]; // UUIDs; default []
}
interface VotingResult {
proposal: string; // UUID
totalVotes: number;
forVotes: number;
againstVotes: number;
abstainVotes: number;
quorumMet: boolean;
thresholdMet: boolean;
winner: string | null;
detailedBreakdown: Record<string, unknown>;
}
ProposalType (PROPOSAL_TYPE_VALUES) covers the 11 recognized kinds of
governance action a proposal can represent:
Constitutional, Legislative, Budgetary, Electoral, Membership,
ParameterChange, TreasuryAllocation, DisputeResolution, Emergency,
Ceremonial, MetaGovernance.
ProposalStatus (PROPOSAL_STATUS_VALUES) tracks the lifecycle of a proposal
through 11 states:
Draft, Discussion, Deliberation, Voting, Passed, Failed, Queued,
Executed, Vetoed, Expired, Cancelled.
VoteChoice is a discriminated union on type, allowing each voting
mechanism to express its ballot format precisely. The type discriminant must
be one of VOTE_CHOICE_TYPE_VALUES: For, Against, Abstain,
RankedChoices, ConvictionAmount, QuadraticCredits, ApprovalSet.
| Discriminant | Extra field |
|---|---|
For |
— |
Against |
— |
Abstain |
— |
RankedChoices |
rankings: { option, rank }[] (≥1) |
ConvictionAmount |
convictionAmount: number (>0) |
QuadraticCredits |
quadraticCredits: number (>0) |
ApprovalSet |
approvals: string[] (≥1) |
3.5 GovernanceFramework#
Defined in types/framework.ts. A GovernanceFramework describes the rules and
parameters under which a specific governance process operates. It is separate
from Organization so that the same framework can be applied to multiple
organizations, and so that an organization can switch frameworks over time by
versioning this object.
interface GovernanceFramework {
type: FrameworkType;
rules: GovernanceRule[]; // ≥1
parameters: GovernanceParameter;
version: string; // 1–64 chars
phases: GovernancePhase[]; // ≥1; defaults to all phases
}
interface GovernanceRule {
condition: string | Record<string, unknown>;
action: string | Record<string, unknown>;
threshold: number; // 0–1
timelock: number; // non-negative integer
vetoPower: { enabled: boolean; vetoRoles: string[]; vetoThreshold?: number };
}
interface GovernanceParameter {
quorumThreshold: number; // 0–1
passingThreshold: number; // 0–1
votingPeriod: number; // positive integer
executionDelay: number; // non-negative integer
proposalDeposit: number; // ≥0
delegationDepth: number; // non-negative integer
}
FrameworkType (FRAMEWORK_TYPE_VALUES) enumerates the 12 recognized
governance system designs the platform can model:
DirectDemocracy, RepresentativeDemocracy, LiquidDemocracy, Sociocracy,
Holacracy, ConsensusGovernance, FutarchyGovernance,
ConvictionGovernance, QuadraticGovernance, BicameralGovernance,
HybridGovernance, CustomFramework.
GovernancePhase (GOVERNANCE_PHASE_VALUES) names the phases a governance
process moves through: discussion, deliberation, voting, execution,
review.
3.6 Deliberation, Argument, CitizenAssembly#
Defined in types/deliberation.ts. These types model structured discussion
before a vote is called. Deliberation produces a ConsensusLevel that informs
whether a proposal is ready to proceed to voting.
interface Deliberation {
topic: string; // 1–255 chars
organization: string; // UUID
participants: string[]; // UUIDs, ≥1
phases: DeliberationPhase[]; // ≥1
facilitator: string; // UUID
outcome: ConsensusLevel | null;
summary: string;
}
interface Argument {
// recursive (z.lazy)
claim: string;
evidence: ArgumentEvidence[];
author: string; // UUID
supportsProposal: boolean;
counterarguments: Argument[];
endorsements: string[]; // UUIDs
qualityScore: number; // 0–1
}
interface ArgumentMap {
rootClaims: Argument[]; // ≥1
relationships: ArgumentRelationship[];
consensusClusters: ConsensusCluster[];
disagreementPoints: string[];
}
interface CitizenAssembly {
sortitionPool: string[]; // UUIDs, ≥1
selectedMembers: string[]; // UUIDs, ≥1
topic: string; // 1–255 chars
duration: { start: string; end: string }; // ISO datetimes
expertWitnesses: CitizenAssemblyExpertWitness[];
recommendations: string[]; // ≥1
}
DeliberationPhase (DELIBERATION_PHASE_VALUES) describes the structured
phases of a formal deliberation session: InformationGathering,
SmallGroupDiscussion, PlenarySession, OpinionPolling, ProposalDrafting,
FinalVote.
ConsensusLevel (CONSENSUS_LEVEL_VALUES) captures the quality of the
agreement reached: StrongConsensus, RoughConsensus, MajorityAgreement,
Divided, Deadlocked.
ArgumentRelationshipType (ARGUMENT_RELATIONSHIP_VALUES) — supports,
rebuts, clarifies, extends.
3.7 Dispute, Ruling, Mediator#
Defined in types/dispute-resolution.ts. Note that these core types define the
data shapes for governance disputes stored in @themis/core; the routing logic
for sending disputes to the Concordia mediation substrate lives in the separate
@themis/dispute-resolution library (§8), and the heavyweight mediation and
arbitration engines live in @themis/arbitration.
interface Dispute {
parties: string[]; // UUIDs, ≥2
subject: string;
evidence: Evidence[];
status: DisputeStatus;
resolutionMethod: ResolutionMethod;
ruling: Ruling | null;
appealStatus: AppealStatus;
}
interface Ruling {
dispute: string; // UUID
adjudicator: string;
decision: string;
reasoning: string;
enforcement: {
actions: string[];
deadline: string | null;
enforcementBody: string;
};
appealDeadline: string | null;
}
interface Mediator {
identity: string;
qualifications: string[]; // ≥1
specializations: string[]; // ≥1
trackRecord: { casesHandled; successfulResolutions; averageResolutionDays };
}
ResolutionMethod (RESOLUTION_METHOD_VALUES) lists the seven ways a dispute
can be resolved: Negotiation, Mediation, Arbitration,
DecentralizedCourt, RestorativeJustice, CommitteeReview, MemberVote.
DisputeStatus (DISPUTE_STATUS_VALUES) tracks where in the resolution
pipeline a dispute sits: filed, review, mediation, arbitration,
adjudicated, appealed, closed.
AppealStatus (APPEAL_STATUS_VALUES) — none, eligible, filed,
under_review, resolved, rejected.
3.8 Treasury and fiscal types#
Defined in types/treasury-fiscal.ts. The treasury types model the financial
governance of an organization — what assets it holds, how those assets may be
spent, and who must authorize spending. These types are used by
@themis/treasury and @themis/funding.
The key entities and their relationships are:
Treasury— top-level holder:organization,assets,totalValue,allocationRules,spendingLimits,signers(≥1).TreasuryAsset— a single asset line in the treasury.TreasuryAllocationRule— a rule constraining how treasury funds may be allocated.TreasurySpendingLimit— a per-category or per-period spending cap.TreasurySigner— an authorized co-signer for treasury transactions.BudgetAllocation— an approved allocation of funds to a purpose.FundingStream— a streaming or vesting distribution, with aFundingVestingSchedule.SpendingProposal/SpendingApproval— the two-step flow for authorizing a disbursement.FiscalPeriod— a time-bounded budget period for reporting and reconciliation.
TreasuryAssetType (TREASURY_ASSET_TYPE_VALUES) — Fiat, Stablecoin,
Token, Equity, Bond, Commodity, NFT, Other.
BudgetExecutionStatus (BUDGET_EXECUTION_STATUS_VALUES) — proposed,
approved, in_execution, completed, cancelled.
FiscalAuditStatus (FISCAL_AUDIT_STATUS_VALUES) — pending, in_review,
approved, qualified, rejected.
3.9 Governance metrics#
Defined in types/governance-metrics.ts. All scores are in the 0–1 range unless
noted. These metric types are computed by @themis/analytics and
@themis/accountability and surfaced to consuming applications for dashboard
display and health alerting.
GovernanceHealthScore— ten sub-scores:participationRate,proposalThroughput,decisionQuality,diversityIndex,transparencyScore,accountabilityScore,legitimacyScore,efficiencyScore,adaptabilityScore,overallHealth.ParticipationMetrics—voterTurnout,proposalAuthors(count),deliberationActive,delegationRate,newMemberRate.DecisionQualityMetrics—implementationSuccessRate,reversalRate,stakeholderSatisfaction,timeToDecision(non-negative),informedVotingRate.TransparencyMetrics—documentAvailability,meetingRecordCompleteness,financialDisclosure,decisionTraceability,auditCompliance.GovernanceMetricsSnapshot— bundles all four metric groups plus ageneratedAttimestamp.
4. Event System (@themis/core events module)#
Every governance action in Themis is expressed as a typed event appended to the immutable audit log. The event system has three parts: the catalogue of event types (§4.1), the event record structure (§4.2), and the hash-chaining and Kafka infrastructure (§4.3).
4.1 Event-type catalogue#
events/types.ts defines THEMIS_EVENT_TYPES, a frozen object of named
event-type string constants. THEMIS_EVENT_TYPE_LIST and
THEMIS_EVENT_TYPE_COUNT are derived from it, and isThemisEventType() is the
runtime guard. Event types are grouped by domain prefix. There are 126
distinct event-type constants across twelve groups:
| Prefix | Coverage |
|---|---|
themis.organization.* |
created, profile updated, jurisdiction added/removed, status changed, merged, dissolved, charter updated, metadata updated |
themis.framework.* |
created, updated, activated, deactivated, rule added/updated/removed, version published, parameter changed |
themis.member.* |
invited, joined, activated, suspended, removed, role assigned/revoked, identity verified/revoked, reputation adjusted, eligibility confirmed/revoked |
themis.delegation.* |
created, changed, revoked, expired, scope updated, power rebalanced, chain updated |
themis.proposal.* |
created, submitted, sponsored, updated, versioned, tagged/untagged, discussion opened, deliberation started/extended, voting started, quorum reached, threshold met, passed, failed, veto exercised, execution queued, executed, cancelled, expired |
themis.vote.* |
cast, updated, invalidated, delegated, tally updated, recount requested/completed, receipt published, proof verified |
themis.deliberation.* |
session created/started, participant joined/left, message posted, phase started/completed, outcome recorded, consensus measured |
themis.constitution.* |
drafted, article added/updated/removed, amendment proposed/adopted/rejected, ratification started, ratified, superseded |
themis.election.* |
announced, nomination opened/closed, candidate registered/withdrawn, voting opened, ballot cast, result recorded, certified, contested, closed |
themis.treasury.* |
created, account added, asset registered, budget proposed/approved, allocation created, transfer initiated/completed, payout executed, rebalanced, stream status changed |
themis.dispute.* |
filed, evidence submitted, mediation started, arbitration started, ruling issued, appeal filed/resolved, resolved, closed |
themis.governance.* |
notification dispatched, integration sync started/completed, risk registered/mitigated, policy document anchored, audit checkpoint created, compliance report generated, health computed/alerted |
THEMIS_EVENT_TYPE_COUNT is derived from the list at runtime, so it always
reflects the actual count in source. There is no themis.license.revoked
event type, and no music/originality shield event types, in the @themis/core
catalogue. (The originality-shield verdict audit event constant — see §7 — lives
in the originality-shield code, not in THEMIS_EVENT_TYPES.)
4.2 Governance event record#
Every governance event is stored as a ThemisGovernanceEvent. The payload
field is typed precisely via a conditional type, so the compiler enforces that a
themis.proposal.* event carries a ProposalEventPayload and not some other
payload shape.
interface ThemisGovernanceEvent<T extends ThemisEventType> {
id: string;
type: T;
organizationId: string;
actorMemberId: string | null;
targetTable: string | null;
targetId: string | null;
payload: ThemisEventPayloadForType<T>; // payload shape inferred from event prefix
metadata: GovernanceEventMetadata; // correlationId?, causationId?, schemaVersion?, labels?
occurredAt: string;
recordedAt: string;
hashPrev: string | null;
hashCurrent: string;
merkleLeafHash: string;
sourceSystem: string | null;
ipAddress: string | null;
}
ThemisEventPayloadForType<T> is a conditional type that maps each event prefix
to a payload interface: OrganizationEventPayload,
GovernanceFrameworkEventPayload, MemberEventPayload,
DelegationEventPayload, ProposalEventPayload, VoteEventPayload,
DeliberationEventPayload, ConstitutionEventPayload, ElectionEventPayload,
TreasuryEventPayload, DisputeEventPayload, and
GovernanceOperationsEventPayload.
4.3 Hash-chained, Merkle-anchored audit log#
The audit log is designed to be tamper-evident. Each event's hash chains over the previous event's hash, and groups of events are organized into a Merkle tree whose root can be anchored on the Ethereum blockchain via the Aje SDK. This means any third party can verify that audit records have not been altered, even without access to the Themis database.
The implementation spans four source files:
events/hash-chain.ts— providescomputeGovernanceEventHashes,computeHashChainCurrent,computeMerkleLeafHash,sha256Hex,toCanonicalJson,normalizeGovernanceJson, and the genesis-hash constantTHEMIS_AUDIT_CHAIN_GENESIS_HASH. Each event'shashCurrentchains over its predecessor's hash; each event also yields a Merkle leaf hash.events/service.ts—ThemisGovernanceEventServiceappends events inside a transaction, taking a per-organization Postgres advisory lock (pg_advisory_xact_lock) so the hash chain is serialized per organization. It also verifies chains (GovernanceChainVerificationReport, with issue codeshash_prev_mismatch,merkle_leaf_mismatch,hash_current_mismatch) and infers a target table from the event type.events/audit-anchor.ts—ThemisGovernanceAuditAnchorServicebatches events into a Merkle tree and anchors the root on-chain. The default anchor chain isethereum; an Ethereum anchorer (AjeEthereumMerkleRootAnchorer,createAjeSdkEthereumAnchorer) integrates with the Aje SDK. The default payload prefix isTHEMIS_AUDIT_ROOT_V1.events/kafka.ts—ThemisKafkaPublisherandInMemoryGovernanceKafkaPublisherpublish governance events to Kafka; default topic fromDEFAULT_THEMIS_GOVERNANCE_KAFKA_TOPIC.
5. Graph Module (@themis/core graph module)#
The graph module answers questions that relational queries handle poorly: who has influence over whom, how does voting power flow through delegation chains, and where are single points of failure in the governance network? It models governance actors and their relationships as nodes and edges in a Cypher-capable graph store.
The key types are:
GovernanceActorType—individual,organization,dao,institution.GovernanceRelationshipType—DELEGATES_TO,MEMBER_OF,REPORTS_TO,CONTROLS,INFLUENCES,OPPOSES,ALLIES_WITH.GovernanceActorNode—actorId,organizationId,actorType,displayName, optionaljurisdiction,metadata.GovernanceRelationshipEdge—fromActorId,toActorId,organizationId,type, optionalweight,confidence,validFrom,validTo,metadata.
ThemisGovernanceGraphService and the Cypher query builders
(buildUpsertActorCypher, buildUpsertRelationshipCypher,
buildPowerFlowAnalysisCypher, buildTopologyQueryCypher,
buildInfluencePathCypher) implement upserts plus power-flow, topology, and
influence-path queries. getThemisGraphSchemaStatements returns the schema
bootstrap statements.
6. Database Schema (@themis/core database module)#
@themis/core ships two SQL migrations, registered through
THEMIS_CORE_MIGRATIONS. All objects live in a dedicated themis PostgreSQL
schema and require the pgcrypto and pg_trgm extensions.
6.1 Migration 20260212150000_themis_governance_schema#
This first migration creates the foundational schema: the themis namespace, 14
PostgreSQL ENUM types, and 63 base tables (plus three audit_events range
partitions). The tables cover every governance entity in the domain:
organizations, organization_profiles, organization_jurisdictions,
members, member_identities, member_roles, delegation_edges,
reputation_scores, reputation_events, governance_frameworks,
governance_framework_versions, governance_framework_rules, constitutions,
constitution_articles, constitution_amendments,
constitution_ratifications, proposal_categories, proposals,
proposal_versions, proposal_sponsors, proposal_sections, proposal_tags,
proposal_status_history, deliberations, deliberation_phases,
deliberation_participants, deliberation_messages, deliberation_outcomes,
votes, vote_receipts, vote_proofs, elections, election_candidates,
election_ballots, election_results, treasuries, treasury_accounts,
treasury_assets, treasury_allocations, treasury_streams,
treasury_transactions, disputes, dispute_parties, dispute_evidence,
dispute_rulings, policy_documents, policy_analyses,
compliance_requirements, compliance_assessments, governance_sessions,
quorum_snapshots, decision_records, public_consultations,
consultation_feedback, funding_rounds, funding_allocations,
simulation_runs, simulation_results, integration_links, risk_register,
notifications, audit_events, audit_hash_checkpoints.
Notable schema features worth understanding before writing queries:
audit_eventsis range-partitioned byoccurred_at, with partitionsaudit_events_2026_h1,audit_events_2026_h2, andaudit_events_default. It carrieshash_prev,hash_current,merkle_leaf_hashcolumns for the hash-chained audit log.audit_hash_checkpointsrecords Merkle roots with on-chain anchoring columns (anchored_chain,anchored_tx_hash,anchored_block_number).- GIN full-text indexes exist on
constitution_articles.body,proposals(title + body),deliberation_messages.body,policy_documents.body, andconsultation_feedback.feedback_text. - The schema's PostgreSQL enums use snake_case values (e.g.
proposal_status=draft, review, deliberation, voting, approved, rejected, executed, withdrawn, expired). These intentionally differ from the TypeScript Zod enums in §3, which use PascalCase; the database layer is a separate storage representation.
6.2 Migration 20260212160000_themis_document_storage#
This second migration adds off-chain document storage support, enabling governance documents (constitutions, policy documents, session minutes, decision records) to be persisted on IPFS or Arweave in addition to the PostgreSQL row. It adds:
- The
governance_document_typeanddocument_storage_statusenums. - The
document_storage_recordsanddocument_storage_eventstables. storage_record_idforeign keys onconstitutions,policy_documents,governance_sessions(minutes), anddecision_records(resolution).
ThemisDocumentStorageService and hashGovernanceDocument implement the
storage layer.
6.3 Migration runner#
Four symbols manage the migration lifecycle: createThemisCoreMigrationService,
migrateThemisCoreUp, migrateThemisCoreDown, and a CLI (migrations/cli.ts).
The migration service takes a Postgres advisory lock
(THEMIS_MIGRATION_LOCK_ID) to prevent concurrent migration runs in
multi-instance deployments.
7. Originality / IP-Protection Shields#
7.1 Architecture#
The originality shields are a thin Themis layer over the @concordia/contracts
originality-shield contract (resolved at libs/contracts/concordia/src →
themis-originality-shield/). Themis does not implement detection algorithms
itself; it constructs an evidence bundle, delegates verdict computation to
evaluateShield from @concordia/contracts, and maps the result to a Themis
decision.
@themis/originality-shields exports buildThemisOriginalityShieldVerdict,
which is the shared implementation. The five media shields each call it with a
fixed config. The table below shows what each shield covers:
| Shield | mediaFamily |
supportedUploadKinds |
Default evidence kind |
|---|---|---|---|
@themis/music-shield |
music |
music-swap, custom-championship |
audio_fingerprint |
@themis/visual-shield |
visual |
custom-championship, decal, logo |
image_perceptual_hash |
@themis/text-shield |
text |
custom-championship, logo |
lyric_text_embedding |
@themis/video-shield |
video |
custom-championship |
video_perceptual_hash |
@themis/design-shield |
design |
custom-championship, decal, logo |
image_perceptual_hash |
Each shield also exports a package-name constant and a shieldId constant (e.g.
THEMIS_MUSIC_SHIELD_ID = 'themis.music-shield.v1') and re-exports the scan
input/verdict types.
7.2 Scan input#
A caller initiates an originality check by providing a
ThemisOriginalityShieldScanInput (validated by a Zod schema). The fields are:
| Field | Type | Notes |
|---|---|---|
uploadId |
string | non-empty |
creatorAccountId |
string | non-empty |
uploadKind |
ThemisOriginalityUgcUploadKind |
custom-championship, decal, logo, music-swap |
contentHashSha256 |
string | matches ^(sha256:)?[A-Fa-f0-9]{64}$ |
sourceUri |
string | non-empty |
createdAtIso |
string | ISO datetime with offset |
referenceMatches |
ThemisOriginalityReferenceMatch[] |
optional; default [] |
licenseLineages |
LicenseLineage[] |
optional; from @concordia/contracts |
reviewerSignedOff |
boolean | default false |
reviewerPartyId |
string | optional |
ThemisOriginalityReferenceMatch carries: matchId, priorWorkId, score01
(0–1), licensed (default false), optional licenseLineageId, optional
region (kind ∈ time_range_seconds, pixel_box, token_range,
mesh_subgraph, lines_range, plus from/to).
7.3 Verdict#
buildThemisOriginalityShieldVerdict returns a
ThemisOriginalityShieldVerdict. The most important fields for consumers are:
decision— the three-value accept-gate result (passed,review,blocked); see the mapping table below.publicUgcAcceptGateStatus—passedonly whendecision === 'passed'; otherwiseblocked. This is the field a UGC upload pipeline should check.highestUnlicensedBand— the most severe confidence band among unlicensed matches.maxSimilarity01— the highest overlap score across all reference matches.blockingReasons— human-readable list of reasons for ablockeddecision.evidenceUri— URI to the evidence bundle for audit purposes.auditEventType— alwaysthemis.originality_shield.verdict_recorded.
Additional envelope fields: schemaVersion: 1, packageName,
corePackageName, sourceContractPackageName, evaluatorVersion
(themis-originality-shields.v1), shieldId, mediaFamily, uploadId,
uploadKind, creatorAccountId, contentHashSha256, sourceUri,
supportedUploadKinds, evidenceBundle (OriginalityEvidenceBundle),
shieldOutcome (ShieldOutcome).
The contract assigns each reference match to one of six confidence bands
based on its overlap score. The default calibration maps score thresholds 0 /
0.2 / 0.45 / 0.65 / 0.8 / 0.95 to the bands inconclusive, low_overlap,
medium_overlap, high_overlap, substantial_match, identical respectively.
ShieldOutcome.verdict (from @concordia/contracts) produces one of seven
verdicts, which Themis collapses into the three-value decision:
Themis decision |
Contract verdicts mapped |
|---|---|
passed |
clear_for_distribution, clear_with_attribution, license_required_obtained |
review |
unverified_chain_route_to_counsel, inconclusive_route_to_human_review |
blocked |
license_required_pending, unlicensed_overlap_blocked |
The evidence-bundle methodology id is <shieldId>:compound-v1.
The elaborate per-engine detection design (melodic / harmonic / rhythmic / spectral / lyric / vocal / structural engines, compound-escalation multipliers, ISRC/ISWC reference databases, perceptual-hash and CLIP/DINOv2 stacks, C2PA labelling) is the planned Phase 74 / Phase 75 scope — see §16. It is not present in the current shield libraries, which are the thin Concordia-backed wrappers described above.
8. Dispute-Resolution Routing (@themis/dispute-resolution)#
@themis/dispute-resolution (tagged phase:179) routes Themis governance
disputes into the Concordia mediation substrate and implements three V2 intake
flows. It depends on @concordia/contracts and zod. It is intentionally small
(≈790 LOC) — the classification and routing logic lives here, but the mediation
and adjudication work itself is handled by Concordia or @themis/arbitration.
8.1 Dispute routing#
ThemisDisputeKind (Zod enum) classifies what kind of governance dispute has
arisen. The nine recognized kinds are:
proposal_amendment, election_challenge, delegate_misconduct,
ip_originality_appeal, moderation_appeal, marketplace_conflict,
inter_dao_agreement, standard_amendment, community_council_dispute.
routeThemisDispute(kind) returns a ThemisRoutingDecision:
{ disputeKind, routeToConcordia, operationalMode, reviewerQueues, rationale }.
shouldRouteToConcordia(kind) is the boolean shorthand.
operationalModeselects how Concordia should run its mediation process. Valid modes:brainstorming,facilitated_mediation,procurement_negotiation,governance_process,arbitration_support,legal_review_required,restorative_circle,agent_to_agent,simulation_only.reviewerQueuesspecifies which specialist queues should be notified. Valid queue identifiers:mediator,counsel,compliance,procurement,dao_steward,safety,governance,auditor.
Every dispute kind routes to Concordia except standard_amendment, which
runs through normal governance rather than mediation.
8.2 V2 dispute flows#
v2-dispute-flows.ts exports package and flow-id constants and three builder
functions used by V2's gaming and tournament platform:
buildThemisDsaStatementOfReasons— builds an EU Digital Services Act Statement of Reasons when content is moderated. Inputs cover:surface∈battle-hub-chat,fighter-chat,replay-comment,creator-suite-upload,profile,ranked-match,tournamentactionType∈content_removed,content_hidden,content_demoted,chat_restricted,creator_upload_rejected,account_suspended,account_banned,matchmaking_restricted,rank_penaltyreasonCategory,factSources,policyBasis
openThemisModerationAppeal— opens a moderation appeal case with a 7-day SLA (THEMIS_MODERATION_APPEAL_SLA_DAYS = 7).openThemisTournamentResultDispute— opens a tournament-result dispute;themisDisputeKindForTournamentResultmaps it to aThemisDisputeKind.
Flow-id constants:
THEMIS_DSA_STATEMENT_OF_REASONS_API_ID = 'themis.dsa.statement-of-reasons.v1',
THEMIS_MODERATION_APPEAL_FLOW_ID = 'themis.moderation-appeal.v1',
THEMIS_TOURNAMENT_RESULT_DISPUTE_FLOW_ID = 'themis.tournament-result-dispute.v1'.
9. Academic-Integrity Adjudication (@themis/academic-integrity)#
@themis/academic-integrity is the Themis adjudication engine for Metis
academic-integrity cases. It exports the themisAcademicIntegrityModule
identifier and six sub-modules. This library depends only on zod — it does not
depend on @themis/core — because it operates as a self-contained adjudication
engine that Metis invokes at the point of a suspected integrity violation.
| Sub-module | File | Responsibility |
|---|---|---|
signals |
signals/taxonomy.ts |
Academic-integrity signal taxonomy |
classifier |
classifier/policy.ts, classifier/severity-actions.ts |
Calibrated classifier policy and severity→action map |
appeals |
appeals/workflow.ts |
Appeals workflow |
bias |
bias/monitor.ts |
Classifier bias monitor |
verdict |
verdict/persistence.ts |
Verdict persistence |
orchestrator |
orchestrator/adjudicator.ts |
End-to-end adjudication orchestration |
10. Module Identifiers#
Most Themis libraries export a module-identifier constant from their index.ts.
This constant allows a host application to verify at runtime which Themis
modules are loaded, without depending on package metadata from the filesystem.
The constant carries only a name field — there is no version field:
// @themis/core
export const themiscoreModule = { name: '@themis/core' } as const;
// @themis/voting
export const themisvotingModule = { name: '@themis/voting' } as const;
The constant name is themis<package>Module in lower case (e.g.
themisaiModule, themisdaoModule). @themis/academic-integrity uses the
PascalCase variant themisAcademicIntegrityModule because of the hyphenated
package name.
The following libraries do not export a module-identifier constant:
@themis/crisis, @themis/international, @themis/justice,
@themis/dispute-resolution, @themis/originality-shields, and the five media
shields (@themis/music-shield, @themis/visual-shield, @themis/text-shield,
@themis/video-shield, @themis/design-shield).
11. NIL / Likeness Ledger (V2 Fighting-Game Consumer)#
The V2 fighting-game product consumes Themis as the authoritative
name-image-likeness (NIL) rights registry for every real-person likeness it
ships — licensed fighters, celebrity guests, stunt performers, and on-stage
venue staff. The canonical registry is a new, Themis-owned library,
@themis/likeness, which is still forthcoming and not yet implemented in
libs/themis/likeness/. It is distinct from @themis/identity (governance
identity — DID, eligibility, Sybil resistance) and from the originality shields
in §7 (which protect uploaded UGC against prior works, not real-person
likeness rights).
Two V2-side bridges already ship against the contract of this forthcoming ledger by structurally typing its stamp and its revocation event, without taking a package dependency on the unbuilt library:
@v2/aja-consent-nil-ledgerlinks each Aja performer-consent record to a@themis/likenessledger entry bylikenessLicenseId,rightsManifestSha256, andconsentChainRefs[], and emits thethemis.license.revokedcascade on withdrawal.@v2/kuanyin-performer-protectionreads a@themis/likenessledger stamp at the chat / commentary / creator-upload boundary and blocks any likeness surface (and the downstream Bellona cook) whose stamp is revoked, expired, out-of-scope, or whoserightsManifestSha256does not match the active manifest.
These V2-side bridges such as @v2/aja-consent-nil-ledger and
@v2/kuanyin-performer-protection are consumer safeguards; they enforce the
ledger contract but they are not the ledger itself. Authoring the canonical
@themis/likeness library remains Themis-owned work — see §11.8.
11.1 The canonical LikenessLicense schema#
The forthcoming @themis/likeness library will own a Zod-validated
LikenessLicense aggregate — the per-subject, per-region, per-license-window
grant of likeness rights. Its identity is a likenessLicenseId (lic_-prefixed
slug, matching the pattern the V2 bridges already validate). Each license
carries:
- Subject identity —
subjectId,subjectDisplayName, andsubjectType(fighter,celebrity,stunt-performer,venue-staff), plus an alias set so downstream protection surfaces can detect mentions. - Rights envelope —
status(draft,active,paused,breach-cure,terminated,expired),validUntilEpochMs(a timestamp orperpetual), the set ofallowedUses(playable character, cinematic cameo, cosmetic skin, voice-line bank, commentary mention, real-world venue stage, soundtrack, promotional art, merchandise spin-off, esports broadcast, creator-suite upload), and the licensedregions. - Provenance —
rightsManifestSha256, an immutablesha256:-prefixed digest of the signed rights manifest, andconsentChainRefs[], the ordered list of consent-record identifiers (from@aja/consent-management) that underwrite the grant. - Per-grant nuance — the schema must model per-mode toggles (a use may be granted in ranked but withheld from exhibition), distinct voice grants (a voice-line bank licensed separately from the visual likeness), group / faction rights (team or roster-level grants that fan out to individual members), sublicensee chains (studio → publisher → platform re-grants, each link auditable), and per-platform-store overrides (a use permitted on one storefront but blocked on another for territorial reasons).
- Estate / postmortem rights — the schema must carry coverage for estate / postmortem rights so a deceased performer's likeness can remain governed by the executor-held grant, including a post-mortem expiry distinct from the living-subject window.
The license aggregate is the single source of truth that the V2 consumer bridges
project into their narrower rightsStamp / ledger-stamp shapes.
11.2 Cook-time rights stamping via @bellona/interchange#
Every asset that embeds a real-person likeness must be stamped at cook time
— the point where Bellona's @bellona/interchange packaging step seals a
shippable asset bundle. The stamp is a compact, signed projection of the
governing LikenessLicense: likenessLicenseId, rightsManifestSha256, the
covered allowedUses, the consentChainRefs[] that back it, and the
themis.license.revoked event topic that the asset's consumers must watch.
@bellona/interchange is the enforcement chokepoint: a bundle whose embedded
likeness has no stamp, an out-of-scope stamp (the asset's actual use is
not in allowedUses), or a stamp whose rightsManifestSha256 does not match
the manifest sealed into the bundle, must be rejected at cook and never
shipped. This mirrors the blocksBellonaCook gate that the V2 bridges already
assert: when the ledger gate fails, the cook is blocked.
11.3 Revocation cascade#
A LikenessLicense can be revoked at any time — a performer withdraws consent,
a contract lapses, an estate objects. Revocation emits a
themis.license.revoked event keyed by likenessLicenseId. The cascade has
three obligations, each of which the V2 consumers already honour:
- Notify the NIL ledger — flip the ledger entry
statustorevoked/terminatedso no new stamp can be minted against it. - Block future processing —
@v2/aja-consent-nil-ledgerblocks further Aja ingest of the performer's capture data, and (when requested) deletes the associated capture data. - Block the cook — any in-flight or future
@bellona/interchangecook of an asset embedding the revoked likeness is blocked, and any live likeness surface (@v2/kuanyin-performer-protection) is shut to viewers.
The Aja consumer commits to executing the cascade within a 15-minute SLA of the
withdrawal request. Revocation is append-only audit history: the ledger keeps
the prior active entry and the revocation event, never a destructive edit.
11.4 Consent-chain validation#
The ledger does not mint or activate a LikenessLicense unless its
consentChainRefs[] resolve to live, in-scope consent records in
@aja/consent-management. Validation requires that every required consent
purpose for the asset's intended uses is consented, that the chain's
rightsManifestSha256 matches the license, and that no referenced consent
record is withdrawn. @v2/aja-consent-nil-ledger builds the chain at grant time
(one ref per ConsentRecord) and is the canonical integration point for this
validation; @themis/likeness will own the validation rule itself.
11.5 DSA Statement-of-Reasons for likeness takedowns#
When a likeness asset is removed, demoted, or blocked because its NIL rights
failed (revoked stamp, expired window, out-of-scope use, manifest mismatch), the
affected creator or rights-holder is owed a machine-readable DSA
Statement-of-Reasons. The ledger does not implement the SoR engine itself; it
delegates to @themis/dispute-resolution, whose
buildThemisDsaStatementOfReasons (§8.2) produces the notice and whose
openThemisModerationAppeal opens the seven-day appeal. @themis/likeness will
author the SoR templates specific to likeness actions (reason categories,
fact sources, policy basis) and hand the structured input to
@themis/dispute-resolution for issuance.
11.6 On-chain manifest publication (optional)#
For high-value grants (celebrity guests, estate-held rights), the ledger may
optionally publish the signed rightsManifestSha256 and license envelope to an
@aje/rwa on-chain real-world-asset manifest, anchoring the grant's provenance
in the same Aje substrate the @themis/core audit-anchor service already uses
(§4.3). On-chain publication is an option, not a requirement: the
in-database ledger remains authoritative; the chain is a tamper-evident mirror.
11.7 Why this is a new library, not an extension#
@themis/likeness is deliberately a separate package rather than an addition to
@themis/identity or the originality shields. Identity governs who may
participate in governance; the originality shields protect uploaded works
against prior art; the likeness ledger governs a real person's right to have
their image, name, and voice embedded in a shipped product. These are distinct
legal regimes (publicity / NIL rights vs. governance identity vs. copyright),
distinct event topics (themis.license.revoked vs.
themis.originality_shield.verdict_recorded), and distinct enforcement
chokepoints (@bellona/interchange cook vs. UGC accept-gate). Collapsing them
would entangle three independent compliance surfaces.
11.8 V2 reciprocal task tracker#
The following work is Themis-owned and remains in this domain backlog. It is the
reciprocal of the V2 consumer bridges that already ship: those bridges enforce a
contract this domain has not yet built. Until @themis/likeness exists, the
contract lives only in the structural types the V2 bridges declare and in this
specification. Each item below is unchecked and must be authored inside the
Themis monorepo.
- Stand up the new
@themis/likenesslibrary underlibs/themis/likeness/withpackage.json(@themis/likeness),project.json(scope:themis,layer:domain,type:lib),tsconfig.json, and Vitest config, separate from@themis/identityand the originality shields. - Implement the canonical
LikenessLicenseschema per § 11.1 as a Zod aggregate withparse*/safeParse*helpers and inferred types re-exported fromlikeness/src/index.ts. - Add schema coverage for estate / postmortem rights, including an
executor-held grant holder and a post-mortem expiry distinct from the
living-subject
validUntilEpochMs. - Implement the cook-time stamp protocol per § 11.2 that projects a
LikenessLicenseinto the signedrightsStamp(likenessLicenseId,rightsManifestSha256,consentChainRefs[], covered uses) that@bellona/interchangeseals into a shippable bundle. - Wire
@bellona/interchangeto reject unstamped or out-of-scope likeness bundles at cook, includingrightsManifestSha256mismatches against the manifest sealed into the bundle. - Implement the revocation cascade per § 11.3 that emits
themis.license.revoked, flips the ledger entry status, and signals the consumer-side blocks (Aja ingest, Bellona cook, live likeness surfaces). - Integrate canonical consent-chain validation with
@aja/consent-managementper § 11.4, rejecting activation when any required purpose is unconsented or any referenced consent record is withdrawn. - Implement venue, music-track, celebrity-guest, logo, and apparel-brand rights families, with per-mode toggles, distinct voice grants, group / faction rights, sublicensee chains, and per-platform-store overrides.
- Add optional
@aje/rwaon-chain manifest publication per § 11.6 for high-value grants, anchoringrightsManifestSha256and the license envelope. - Author DSA Statement-of-Reasons templates for likeness takedowns and route
them through
@themis/dispute-resolutionper § 11.5, opening the seven-day moderation appeal where the action is contestable.
12. Cross-Domain Integrations (@themis/integrations)#
@themis/integrations contains bridges to other Oshun domains. Each bridge is a
separate source file responsible for the data and control flow between Themis
and one counterpart domain. The files present in source are:
| Bridge file | Counterpart domain |
|---|---|
veritas-themis-intelligence-pipeline.ts |
Veritas (inbound) |
themis-veritas-governance-feed.ts |
Veritas (outbound) |
governance-journalism-collaboration-hub.ts |
Veritas |
veritas-open-journalism-governance.ts |
Veritas |
themis-aje-governance-execution-bridge.ts |
Aje (on-chain execution) |
aje-themis-governance-data-ingestion.ts |
Aje (data ingestion) |
maat-themis-organizational-governance.ts |
Maat |
themis-maat-governance-intelligence.ts |
Maat |
lakshmi-themis-fiscal-governance.ts |
Lakshmi |
kuan-yin-themis-ethical-governance.ts |
Kuanyin |
iris-themis-governance-assistant.ts |
Iris |
sophia-themis-knowledge-governance.ts |
Sophia |
metis-themis-civic-education.ts |
Metis |
maya-themis-virtual-governance.ts |
Maya |
sector-specific-governance-bridges.ts |
Sector-specific |
The Aje bridge pair is a representative example of how cross-domain boundaries
are handled. themis-aje-governance-execution-bridge.ts translates a Themis
governance decision (proposal passed, treasury disbursement approved) into an
Aje on-chain execution call. aje-themis-governance-data-ingestion.ts flows in
the other direction, pulling on-chain DAO votes and treasury events back into
Themis for analysis and display. Neither direction owns the other's concerns.
The audit-anchor service in @themis/core also integrates with the Aje SDK for
Merkle-root anchoring (§4.3).
13. Configuration#
@themis/core reads its PostgreSQL connection from environment variables via
resolveThemisPostgresConfigFromEnv (database/migrations/service.ts):
| Variable | Default | Purpose |
|---|---|---|
THEMIS_DB_HOST |
127.0.0.1 |
PostgreSQL host |
THEMIS_DB_PORT |
5432 |
PostgreSQL port |
THEMIS_DB_NAME |
oshun_dev |
Database name |
THEMIS_DB_USER |
postgres |
Database user |
THEMIS_DB_PASSWORD |
postgres |
Database password |
THEMIS_DB_SSL |
false |
Enable SSL when set to true |
There is no THEMIS_DATABASE_URL, THEMIS_BLOCKCHAIN_RPC_URL,
THEMIS_CHAIN_ID, THEMIS_MUSIC_SHIELD_THRESHOLD, or
THEMIS_AUDIT_LOG_BLOCKCHAIN variable in the codebase. Blockchain configuration
for the audit-anchor service is passed programmatically via
AjeEthereumMerkleRootAnchorerConfig / AjeSdkEthereumAnchorerConfig, not via
environment variables. AI-agent libraries that call the Claude API rely on the
monorepo-wide ANTHROPIC_API_KEY convention.
14. Voting Mechanisms (@themis/voting)#
@themis/voting ships 12 voting mechanism files (one source module each).
Each mechanism is self-contained: it defines its own ballot format, tallying
logic, and result computation. The mechanisms share no implementation code —
each is independently testable and deployable.
The twelve mechanism modules are:
universal-ballot-system, delegation-engine, token-weighted-voting,
quadratic-voting, ranked-choice-voting, approval-voting,
condorcet-voting, conviction-voting-engine, holographic-consensus,
optimistic-governance, vote-escrow-governance, multi-sig-voting.
Indicative mechanism parameters (from the engine implementations):
- Quadratic voting — cost grows with the square of votes on an option; voters spend from a voice-credit budget.
- Conviction voting — conviction accumulates over time toward a staked proposal; later staking has less effect than sustained staking.
- Holographic consensus — staked attention fast-tracks proposals to the full DAO; routine proposals resolve locally.
- Quadratic funding — matching is computed from the squared sum of
contribution square roots (see
@themis/funding).
15. Acceptance Criteria#
A change to the Themis domain is acceptance-complete when all six conditions are satisfied:
- Build —
npx tsc --noEmitpasses in each touched library (Nx is unreliable under worktrees; type-check directly from the library directory). - Tests —
npx vitest runpasses in each touched library; the domain uses Vitest with per-library configs andvitest.shared.ts. - Core types — new domain objects added to
@themis/coreare Zod schemas with inferred types andparse*/safeParse*helpers, re-exported fromcore/src/index.ts. - Events — new governance event types are registered in
THEMIS_EVENT_TYPES, carry a payload interface, and append through the hash-chainedThemisGovernanceEventService. - Schema — new persistent tables are added through a
@themis/coremigration in thethemisschema and registered inTHEMIS_CORE_MIGRATIONS. - Lint — the shared
eslint.config.js/prettier.config.jspass.
16. Planned Work#
The following are documented in the V1 backlog (TODOS.md) or V2 dependency
docs as planned, not implemented. They are listed for traceability; nothing
below should be read as describing existing code.
- Phase 74 — Themis Music Shield. A full AI-music copyright-protection and
originality-verification system for
@themis/music-shield, with per-element detection engines and pipeline orchestration. Reference proposal:docs/domains/themis-music-shield-proposal.md. The current@themis/music-shieldlibrary is the thin Concordia-backed wrapper in §7, not this system. - Phase 75 — Themis Universal Originality Shield. Extension of Phase 74 to
every generated media type, with
@themis/visual-shield,@themis/text-shield,@themis/video-shield, and@themis/design-shieldcarrying media-specific detection. Reference proposal:docs/domains/themis-universal-originality-shield-proposal.md. @themis/likeness(forthcoming). The NIL / likeness ledger is specified in full in §11, with its reciprocal Themis-owned task tracker in §11.8. V2 dependency docs (V2/V2_DEPENDENCIES.md) describe the same forthcoming, not-yet-created@themis/likenesslibrary: a per-fighter / per-region / per-license-window name-image-likeness (NIL) ledger, explicitly noted as a new package separate from@themis/identity(whose scope is governance identity — DID, eligibility, Sybil resistance). No@themis/likenesspackage, noLikenessLicensetype, and nothemis.license.revokedevent exist in the codebase today.- Phase 179 — Concordia integration.
@themis/dispute-resolution(§8) is the implemented routing layer for this phase. Further mediated-amendment workflow expansion remains backlog.
V2 consumes Themis libraries through V2-side adapter packages
(@v2/themis-originality-shields, @v2/themis-dispute-resolution,
@v2/themis-community-governance, and others). Those adapters live in the V2
sister-monorepo and are documented there; they are not Themis libraries.
17. V2 Consumer Contracts#
The V2 fighting-game product binds several Themis libraries through thin V2-side
service packages. Each binding is off rollback: it produces governance,
moderation, disclosure, or voting outcomes that never read or write a live
rollback-netcode frame and never influence deterministic simulation
(offRollback: true, mayInfluenceRollback: false,
deterministicImpact: 'none'). The sections below record the contract each
binding upholds against the Themis source of truth.
17.1 V2 Community Governance Contract#
@v2/themis-community-governance projects Themis social governance for the four
V2 player-community surfaces — crew, clique, stable, and faction — onto the
real @themis/community managers. Crew, clique, and faction rule changes run
through SportsClubGovernanceManager (createRulesCommittee,
proposeRuleChange, castRuleProposalVote, finalizeRuleProposal); stable
constitutions run through AssociationGovernanceManager
(proposeConstitutionalAmendment → ratification → enactRatifiedAmendment).
The contract surface owns three projections:
- rule committees — every rule change is sponsored by a committee of at
least three members; a faction rule cannot publish (
crewRulesPublicationGateflips tohold-for-revision) unless the committee vote is approved. - member reputation projection — a
governanceReputationScore(0–100) and atrusted/good/probation/limitedstanding are derived from activity, committee membership, voting participation, and leadership role; the score gates who may sponsor a rule change. - constitution ratification — stable amendments require member ratification voting against quorum and approval thresholds before enactment.
All of this stays off rollback: community governance is social metadata, not
gameplay state, and the V2 binding asserts offRollback: true.
17.2 V2 Dispute-Resolution Contract (DSA appeals + tournament disputes)#
@v2/themis-dispute-resolution binds @themis/dispute-resolution (§8) to the
V2 product's two contestable surfaces. moderation appeals open through
openThemisModerationAppeal with the seven-day Themis SLA and a
machine-readable DSA Statement-of-Reasons; tournament-result disputes open
through openThemisTournamentResultDispute, which holds the provisional result
and routes the challenge to auditor-backed review. Both flows stay off rollback
— they adjudicate after the fact and never touch the deterministic match frame.
17.3 V2 Performer-Protection cross-reference#
@v2/kuanyin-performer-protection (owned by Kuanyin, backed by the
@kuanyin/performer-protection library, specified on the Kuanyin side) is the
live-surface consumer of the forthcoming Themis NIL ledger described in §11. It
reads a @themis/likeness ledger stamp at the chat, commentary-mention, and
creator-suite-upload boundaries, compares the stamp's rightsManifestSha256 and
consentChainRefs against the active manifest, and blocks the likeness surface
and downstream Bellona cook when the stamp is revoked
(themis.license.revoked), expired, out-of-scope, or mismatched. It takes no
package dependency on the unbuilt @themis/likeness library — it binds the
contract structurally. The canonical ledger work that backs this consumer is
tracked in §11.8.
17.4 V2 EU AI Act surface (Themis side)#
Themis is the AI-system-of-record owner for every shipping V2 AI service
under the EU AI Act conformity surface. @themis/accountability
(v2-ai-system-record.ts) registers the V2 Adaptive AI Director, the AI
commentary service, the anti-cheat classifier suite, and the V2 generation
pipelines as regulator-ready AI-system-of-record entries with evidence links.
The Model Cards for those systems are hosted by @nous/safety; Themis owns the
audit export and applies the retain-for-product-lifetime-plus-six-years
retention policy to each record. The composed @v2/eu-ai-act-surface package
wires Psyche transparency, the Nous Model Card, and the Themis accountability
record together; AI commentary is bound as off-rollback presentation content and
never gates a deterministic frame.
17.5 V2 Photo Mode Tournament Voting Profile#
@v2/photo-mode-tournament-voting-bridge binds @themis/voting to community
photo-mode tournaments under the V2 Photo Mode Tournament Voting Profile
(v2.photo-mode-tournament-voting-profile). Jury rounds tally with the
RankedChoiceVotingEngine; broad community rounds tally with the
ApprovalVotingEngine. A @kuanyin/precognition moderation pre-pass screens
each submission before it becomes vote-eligible, and ballots referencing
moderated-out or unknown submissions are sanitized. The whole profile is off
rollback — it ranks gallery content after matches, never during live gameplay
frames.
17.6 V2 World Boss Governance Contract#
@v2/world-boss-community-raid-bridge binds @themis/community (alongside Maat
intelligence, Hathor simulation, and Kuanyin raid defense) for community
world-boss events under the V2 World Boss Governance Contract. Themis owns
the rules for the community-shared HP pool: the rule committee must approve
the shared-HP-and-contribution rule proposal before the raid manifest can
publish. Per-fighter contributions are validated server-side against the
v2.world-boss-contribution-validation schema (golden-replay hash, anti-cheat
acceptance, event-window bounds, per-match damage cap) at match end only. The
shared HP bar is HUD-display-only and gameplay-inert; the bridge rejects any
live rollback-frame RPC and performs no live shared-HP reads, keeping the entire
contract off rollback.