Version 0.9 — March 2026
Council Protocol$VOTIVE is a utility token that governs access, participation, and value exchange within the Council Protocol — a platform for curating, generating, and experiencing multimedia content across domains (visual art, music, literature, live performance). Rather than speculative trading, $VOTIVE functions as a metered access layer: users spend tokens to consume AI-powered services, earn tokens through contribution, and anchor significant transactions to the Solana blockchain for tamper-evident auditability.
The system is designed so that a new user can participate meaningfully with zero upfront cost, while heavy or commercial usage sustains the platform economically.
Content platforms face a trilemma:
$VOTIVE solves this by internalizing the unit of account. Users hold a balance of platform credits denominated in $VOTIVE. Operations are priced at sub-cent granularity (as low as $0.001), eliminating payment-processor minimums. The token is not a cryptocurrency in the speculative sense — it is a metered utility credit with optional chain anchoring for provenance.
$VOTIVE balances are stored with 8 decimal places of precision, allowing pricing from $0.00000001 to $9,999,999,999.99999999 — covering everything from micro-interactions to large contract stakes.
class Wallet(models.Model): user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE) token_symbol = models.CharField(max_length=32) # $BANGER, $ZEUS, $VOTIVE, etc. balance = models.DecimalField(max_digits=18, decimal_places=8, default=0) class Meta: unique_together = ('user', 'token_symbol')
class Transaction(models.Model): TX_TYPES = [ ('credit', 'Credit'), # Tokens added (earnings, refunds) ('debit', 'Debit'), # Tokens spent on operations ('consume', 'Consume'), # Platform credit expiry ('grant', 'Grant'), # Platform-issued credits (welcome drip) ] wallet = models.ForeignKey(Wallet, on_delete=models.CASCADE) tx_type = models.CharField(max_length=8, choices=TX_TYPES) amount = models.DecimalField(max_digits=18, decimal_places=8) attestation_id = models.CharField(max_length=128, blank=True) description = models.CharField(max_length=256, blank=True) created_at = models.DateTimeField(auto_now_add=True)
New wallets receive a 10 $VOTIVE grant on creation. At default chat pricing ($0.01/interaction), this funds approximately 1,000 text interactions.
wallet, created = Wallet.objects.get_or_create(
user=user, token_symbol='$VOTIVE',
defaults={'balance': Decimal('10')} # Welcome drip for new wallets
)
The Wallet model supports arbitrary token symbols ($VOTIVE, $BANGER, $ZEUS), enabling domain-specific economies on shared infrastructure. Each (user, token_symbol) pair maintains an independent balance via the unique_together constraint shown above.
Operations are priced by computational cost and value delivered:
BASE_COSTS = {
# Tier 0 — Free
'status': Decimal('0'),
'balance': Decimal('0'),
'help': Decimal('0'),
# Tier 1 — Micro ($0.001)
'search': Decimal('0.001'),
'seat_info': Decimal('0.001'),
'email_search': Decimal('0.01'),
# Tier 2 — Standard ($0.01)
'chat': Decimal('0.01'),
# Tier 3 — Enhanced
'caption': Decimal('0.02'),
'narrate': Decimal('0.03'),
# Tier 4 — Session
'persona_session': Decimal('0.05'),
'cluster_advise': Decimal('0.05'),
'calendar_create': Decimal('0.05'),
# Tier 5 — Compute
'scenario_react': Decimal('0.08'),
'voice_gen': Decimal('0.10'),
'email_send': Decimal('0.10'),
'embedding_gen': Decimal('0.15'),
'backup_trigger': Decimal('0.20'),
'image_gen': Decimal('0.50'),
'lora_train': Decimal('5.00'),
}
COSMOS_COSTS = {
'seat_assign': Decimal('0.10'), # Assign entity to cosmos seat
'seat_unseat': Decimal('0.05'), # Remove from seat
'forge_scene': Decimal('0.08'), # Per-model scene reaction
'forge_followup': Decimal('0.05'), # Per-model follow-up turn
'gala_address': Decimal('0.05'), # Per-model gala reaction
'snapshot_save': Decimal('0'), # Free — config management
'snapshot_restore': Decimal('0.02'), # Small cost to restore
'contract_stake': Decimal('0.25'), # Stake for contract creation
'contract_fulfill': Decimal('0'), # Free — fulfillment IS the reward
}
Live streams support token-gated access with configurable economics:
class Stream(models.Model): # ... status, title, etc. gate_token_symbol = models.CharField(max_length=32, default='$VOTIVE') gate_min_balance = models.DecimalField(max_digits=18, decimal_places=8, default=0) cost_per_minute = models.DecimalField(max_digits=18, decimal_places=8, default=0) vod_price = models.DecimalField(max_digits=18, decimal_places=8, default=0) # Revenue split: {"streamer": 0.70, "platform": 0.20, "regen": 0.10}
class ContentUnlock(models.Model): """Tracks which photos a user has unlocked via $VOTIVE spend.""" user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE) photo = models.ForeignKey('council.Picture', on_delete=models.CASCADE) cost = models.DecimalField(max_digits=18, decimal_places=8, default=0.25) unlocked_at = models.DateTimeField(auto_now_add=True) class Meta: unique_together = ('user', 'photo') # One unlock per user per item
Every pricing calculation is modified by the user's trust level:
TRUST_MULTIPLIERS = {
'owner': Decimal('0'), # All operations free
'paired': Decimal('0.5'), # 50% discount
'public': Decimal('1'), # Standard pricing
'unknown': Decimal('2'), # 2x premium (unrecognized)
}
Trust is resolved via PaymentPolicy records. The gate checks if the sender ID appears in owner_ids or paired_ids policies, falling back to public for recognized users and unknown for unrecognized ones.
Users interacting via external channels are mapped to internal accounts via a deterministic hash, creating persistent identity without registration:
# Deterministic identity from channel + sender username = f"claw_{channel}_{hashlib.sha256(sender_id.encode()).hexdigest()[:8]}"
Users earn $VOTIVE through platform contribution. Two earn tables operate independently:
EARN_RATES = {
'photo_upload': Decimal('0.50'),
'photo_caption': Decimal('0.10'),
'attestation': Decimal('0.05'),
'referral': Decimal('2.00'),
'votive_cast': Decimal('0.02'),
}
COSMOS_EARN = {
'gala_participate': Decimal('0.03'), # Each gala scene you forge
'seat_assign_first': Decimal('0.50'), # First time seating a model
'forge_scene': Decimal('0.02'), # Creating a scene
}
A Votive is a typed, sentiment-tagged declaration directed at an entity or bucket. Votives are the protocol's native unit of human expression.
class Votive(models.Model): TYPES = [ ('confession', 'Confession'), ('wish', 'Wish'), ('secret', 'Secret'), ('oath', 'Oath'), ('curse', 'Curse'), ] votive_type = models.CharField(max_length=16, choices=TYPES) bucket = models.ForeignKey(Bucket, on_delete=models.CASCADE) sentiment = models.CharField(max_length=16) # positive/negative/neutral emotion = models.CharField(max_length=32) intensity = models.PositiveSmallIntegerField(default=5) # 1-10 scale keywords_hash = models.CharField(max_length=128) # SHA-256 (privacy-preserving) content_hash = models.CharField(max_length=128) # For chain anchoring ipfs_cid = models.CharField(max_length=128) # Optional IPFS pin target_model = models.ForeignKey('council.FemaleModel', null=True, blank=True, on_delete=models.SET_NULL) cost_burned = models.DecimalField(max_digits=18, decimal_places=8, default=0)
class Bucket(models.Model): name = models.CharField(max_length=64, unique=True) # relationships, fear, etc. domain = models.CharField(max_length=64, default='doppelbanger') votive_count = models.PositiveIntegerField(default=0) current_tier = models.PositiveSmallIntegerField(default=0) # Tiers: 0=sealed, 1=sentiment(100), 2=keywords(500), # 3=temporal(1000), 4=corpus(5000), 5=cross(10000)
| Tier | Threshold | Capability Unlocked |
|---|---|---|
| 0 | 0 | Sealed — collection only |
| 1 | 100 | Sentiment analysis |
| 2 | 500 | Keyword extraction |
| 3 | 1,000 | Temporal pattern analysis |
| 4 | 5,000 | Full corpus analysis |
| 5 | 10,000 | Cross-bucket correlation |
class Bounty(models.Model): TYPES = [ ('task', 'Task'), # Work to be completed ('policy', 'Policy'), # Governance proposal ('value', 'Value'), # Community-aligned objective ] STATUSES = [ ('open', 'Open'), ('claimed', 'Claimed'), ('completed', 'Completed'), ('expired', 'Expired'), ('enacted', 'Enacted'), ] bounty_type = models.CharField(max_length=16, choices=TYPES) poster = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE) title = models.CharField(max_length=256) reward_amount = models.DecimalField(max_digits=18, decimal_places=8) reward_token = models.CharField(max_length=32, default='$BANGER') deadline = models.DateTimeField() status = models.CharField(max_length=16, choices=STATUSES, default='open') # Policy-specific fields policy_text = models.TextField(blank=True) threshold_tvl = models.DecimalField(max_digits=18, decimal_places=8, default=0) revenue_share = models.DecimalField(max_digits=5, decimal_places=4, default=0)
Lifecycle: Poster creates bounty with reward → Claimer stakes and submits work → Verification → Payout. Unclaimed bounties expire; staked tokens return.
class ModelContract(models.Model): title = models.CharField(max_length=256) status = models.CharField(max_length=12, choices=STATUS_CHOICES, default='draft') parties = models.ManyToManyField('council.FemaleModel', related_name='contracts') attestation_id = models.CharField(max_length=128) content_hash = models.CharField(max_length=128) stake_amount = models.DecimalField(max_digits=18, decimal_places=8, default=0) token_symbol = models.CharField(max_length=32, default='$VOTIVE')
Each contract event computes a content hash and links to its predecessor, forming a tamper-evident chain:
def compute_and_set_hash(self): payload = json.dumps({ 'contract_id': self.contract_id, 'event_type': self.event_type, 'description': self.description, 'obligation_id': self.obligation_id, 'actor_id': self.actor_id, 'timestamp': datetime.now(timezone.utc).isoformat(), }, sort_keys=True) self.content_hash = hashlib.sha256(payload.encode()).hexdigest() self.prev_hash = self.contract.get_chain_tip() # Link to predecessor
Every significant operation produces an AttestationLog entry with chain-linking fields:
class AttestationLog(models.Model): attestation_id = models.CharField(max_length=128, unique=True) att_type = models.CharField(max_length=64) # contract.signed, votive.confession subject = models.CharField(max_length=256) # council_core.votive:42 action = models.CharField(max_length=256) node_id = models.CharField(max_length=64) attester_pubkey = models.CharField(max_length=128) content_hash = models.CharField(max_length=128) # SHA-256 of content ipfs_cid = models.CharField(max_length=128) # Optional IPFS pin prev_hash = models.CharField(max_length=128) # Chain link # Anchoring lifecycle ANCHOR_CHOICES = [ ('pending', 'Pending'), ('ipfs_pinned', 'IPFS Pinned'), ('chain_anchored', 'Chain Anchored'), ('failed', 'Failed'), ('skipped', 'Skipped'), ] anchor_status = models.CharField(max_length=20, choices=ANCHOR_CHOICES, default='pending') anchor_tx = models.CharField(max_length=256) # Solana tx sig
SOLANA_MODE = os.environ.get('SOLANA_MODE', 'parrot') SOLANA_RPC_URL = os.environ.get('SOLANA_RPC_URL', 'https://api.devnet.solana.com') SOLANA_KEYPAIR = os.environ.get('SOLANA_KEYPAIR_PATH', '') ANCHOR_PROGRAM = os.environ.get('ANCHOR_PROGRAM_ID', 'CouncilProtocolAnchorXXX...')
| Mode | Behavior | Cost |
|---|---|---|
| parrot | Mock — deterministic fake signatures, zero network calls | Free |
| devnet | Solana devnet — real transactions on test cluster | Free (devnet SOL) |
| mainnet | Production chain anchoring | SOL fees |
Uses the standard SPL Memo Program — no custom on-chain program required:
memo_text = f"cc:anchor:{content_hash[:32]}:{subject[:32]}" MEMO_PROGRAM = Pubkey.from_string("MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr") ix = Instruction( program_id=MEMO_PROGRAM, accounts=[], data=memo_text.encode(), ) msg = Message.new_with_blockhash([ix], kp.pubkey(), blockhash) tx = Transaction([kp], msg, blockhash)
def _parrot_anchor(content_hash, subject='', memo=''): # Deterministic fake sig (reproducible = testable) fake_sig = hashlib.sha256( f"parrot:{content_hash}:{subject}:{memo}".encode() ).hexdigest()[:88] # Solana sigs are 88 base58 chars return { 'ok': True, 'mode': 'parrot', 'tx_sig': fake_sig, 'content_hash': content_hash, }
The Votive Gate is the central access-control checkpoint for all AI-powered operations:
def cosmos_debit(user, operation, count=1, description=''): cost = cosmos_cost(operation, count) if cost <= 0: return {'ok': True, 'cost': Decimal('0')} wallet, created = Wallet.objects.get_or_create( user=user, token_symbol='$VOTIVE', defaults={'balance': Decimal('10')} ) if wallet.balance < cost: return {'ok': False, 'error': f'Insufficient $VOTIVE: need {cost}, have {wallet.balance}'} with db_transaction.atomic(): # Atomic — no partial state wallet.balance -= cost wallet.save() Transaction.objects.create( wallet=wallet, tx_type='debit', amount=cost, description=description, )
If an agent dispatch fails after payment, the gate automatically refunds by looking up the original transaction via attestation_id and issuing a credit for the same amount. Users never pay for failed operations.
transaction.atomic(), preventing partial stateprev_hash, making tampering detectableattestation_id lookup| Component | Status |
|---|---|
| Wallet + Transaction ledger | Production |
| Votive Gate (pre/post dispatch) | Production |
| Cosmos Economy bridge | Production |
| Attestation logging | Production |
| Votive casting + buckets | Production |
| Bounty marketplace | Models ready, UI in progress |
| Contract system | Production |
| Solana anchoring (parrot) | Production |
| Solana anchoring (devnet/mainnet) | Ready, pending keypair |
| IPFS pinning | Schema ready |
| Content unlock gating | Production |
| Stream token gating | Production |
| Multi-token wallets | Production |
$VOTIVE is a utility credit within the Council Protocol. It is not a security, investment contract, or speculative instrument. No promises of future value are made or implied.