# Themis Domain — Technical Specifications

---

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.

```typescript
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.

```typescript
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).

```typescript
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.

```typescript
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.

```typescript
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.

```typescript
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`.

```typescript
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 a
  `FundingVestingSchedule`.
- **`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 a
  `generatedAt` timestamp.

---

## 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.

```typescript
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`** — provides `computeGovernanceEventHashes`,
  `computeHashChainCurrent`, `computeMerkleLeafHash`, `sha256Hex`,
  `toCanonicalJson`, `normalizeGovernanceJson`, and the genesis-hash constant
  `THEMIS_AUDIT_CHAIN_GENESIS_HASH`. Each event's `hashCurrent` chains over its
  predecessor's hash; each event also yields a Merkle leaf hash.
- **`events/service.ts`** — `ThemisGovernanceEventService` appends 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 codes
  `hash_prev_mismatch`, `merkle_leaf_mismatch`, `hash_current_mismatch`) and
  infers a target table from the event type.
- **`events/audit-anchor.ts`** — `ThemisGovernanceAuditAnchorService` batches
  events into a Merkle tree and anchors the root on-chain. The default anchor
  chain is `ethereum`; an Ethereum anchorer (`AjeEthereumMerkleRootAnchorer`,
  `createAjeSdkEthereumAnchorer`) integrates with the Aje SDK. The default
  payload prefix is `THEMIS_AUDIT_ROOT_V1`.
- **`events/kafka.ts`** — `ThemisKafkaPublisher` and
  `InMemoryGovernanceKafkaPublisher` publish governance events to Kafka; default
  topic from `DEFAULT_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`, optional `jurisdiction`, `metadata`.
- **`GovernanceRelationshipEdge`** — `fromActorId`, `toActorId`,
  `organizationId`, `type`, optional `weight`, `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_events` is **range-partitioned by `occurred_at`**, with partitions
  `audit_events_2026_h1`, `audit_events_2026_h2`, and `audit_events_default`. It
  carries `hash_prev`, `hash_current`, `merkle_leaf_hash` columns for the
  hash-chained audit log.
- `audit_hash_checkpoints` records 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`, and
  `consultation_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_type` and `document_storage_status` enums.
- The `document_storage_records` and `document_storage_events` tables.
- `storage_record_id` foreign keys on `constitutions`, `policy_documents`,
  `governance_sessions` (minutes), and `decision_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`** — `passed` only when `decision === 'passed'`;
  otherwise `blocked`. 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 a `blocked`
  decision.
- **`evidenceUri`** — URI to the evidence bundle for audit purposes.
- **`auditEventType`** — always `themis.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.

- **`operationalMode`** selects 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`.
- **`reviewerQueues`** specifies 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`, `tournament`
  - `actionType` ∈ `content_removed`, `content_hidden`, `content_demoted`,
    `chat_restricted`, `creator_upload_rejected`, `account_suspended`,
    `account_banned`, `matchmaking_restricted`, `rank_penalty`
  - `reasonCategory`, `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;
  `themisDisputeKindForTournamentResult` maps it to a `ThemisDisputeKind`.

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:

```typescript
// @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-ledger` links each Aja performer-consent record to a
  `@themis/likeness` ledger entry by `likenessLicenseId`,
  `rightsManifestSha256`, and `consentChainRefs[]`, and emits the
  `themis.license.revoked` cascade on withdrawal.
- `@v2/kuanyin-performer-protection` reads a `@themis/likeness` ledger 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 whose `rightsManifestSha256` does 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`, and `subjectType`
  (`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 or `perpetual`),
  the set of `allowedUses` (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 licensed `regions`.
- **Provenance** — `rightsManifestSha256`, an immutable `sha256:`-prefixed
  digest of the signed rights manifest, and `consentChainRefs[]`, 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:

1. **Notify the NIL ledger** — flip the ledger entry `status` to `revoked` /
   `terminated` so no new stamp can be minted against it.
2. **Block future processing** — `@v2/aja-consent-nil-ledger` blocks further Aja
   ingest of the performer's capture data, and (when requested) deletes the
   associated capture data.
3. **Block the cook** — any in-flight or future `@bellona/interchange` cook 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/likeness` library under `libs/themis/likeness/`
      with `package.json` (`@themis/likeness`), `project.json` (`scope:themis`,
      `layer:domain`, `type:lib`), `tsconfig.json`, and Vitest config, separate
      from `@themis/identity` and the originality shields.
- [ ] Implement the canonical `LikenessLicense` schema per § 11.1 as a Zod
      aggregate with `parse*` / `safeParse*` helpers and inferred types
      re-exported from `likeness/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
      `LikenessLicense` into the signed `rightsStamp` (`likenessLicenseId`,
      `rightsManifestSha256`, `consentChainRefs[]`, covered uses) that
      `@bellona/interchange` seals into a shippable bundle.
- [ ] Wire `@bellona/interchange` to reject unstamped or out-of-scope likeness
      bundles at cook, including `rightsManifestSha256` mismatches 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-management` per § 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/rwa` on-chain manifest publication per § 11.6 for
      high-value grants, anchoring `rightsManifestSha256` and the license
      envelope.
- [ ] Author DSA Statement-of-Reasons templates for likeness takedowns and route
      them through `@themis/dispute-resolution` per § 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:

1. **Build** — `npx tsc --noEmit` passes in each touched library (Nx is
   unreliable under worktrees; type-check directly from the library directory).
2. **Tests** — `npx vitest run` passes in each touched library; the domain uses
   Vitest with per-library configs and `vitest.shared.ts`.
3. **Core types** — new domain objects added to `@themis/core` are Zod schemas
   with inferred types and `parse*` / `safeParse*` helpers, re-exported from
   `core/src/index.ts`.
4. **Events** — new governance event types are registered in
   `THEMIS_EVENT_TYPES`, carry a payload interface, and append through the
   hash-chained `ThemisGovernanceEventService`.
5. **Schema** — new persistent tables are added through a `@themis/core`
   migration in the `themis` schema and registered in `THEMIS_CORE_MIGRATIONS`.
6. **Lint** — the shared `eslint.config.js` / `prettier.config.js` pass.

---

## 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-shield` library 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-shield`
  carrying 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/likeness` library: 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/likeness` package,
  no `LikenessLicense` type, and no `themis.license.revoked` event 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 (`crewRulesPublicationGate`
  flips to `hold-for-revision`) unless the committee vote is approved.
- **member reputation projection** — a `governanceReputationScore` (0–100) and a
  `trusted` / `good` / `probation` / `limited` standing 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.
