Skip to main content

Task Rewards System — Learnable Experience & MorphCoin Marketplace

Feature ID: task-rewards-v1 Version: V1.1 (post-launch enhancement) Status: Design Created: 2026-02-14 Estimated Implementation: 6-8 hours Related: Crypto Marketplace (MorphCoin → blockchain in V2.5+)


Vision

Transform tasks from simple to-dos into learnable experiences by tracking completion patterns, success rates, and reward outcomes. This data becomes valuable training data for AI reinforcement learning and can be sold via the MorphCoin marketplace.

Core insight: Every completed task is a data point. Aggregate this across users → AI learns what works. Users earn MorphCoin by contributing quality task performance data.


User Stories

Parent: "I want Morphee to learn which rewards actually motivate my kids to complete homework tasks, so it can suggest better rewards over time."

Teacher: "I want to see class-wide task completion rates to identify which assignment structures work best, and contribute that insight to the broader education community."

Manager: "I want to track team task velocity and success patterns, then sell anonymized productivity insights to leadership consulting firms."

Kid: "I want to earn MorphCoin every time I complete a task with a good success rate, so I can unlock premium Morphee features."


Data Model

Enhanced Task Schema

Add these fields to the existing tasks table:

-- Migration: Add task rewards tracking
ALTER TABLE tasks ADD COLUMN reward BOOLEAN DEFAULT FALSE;
ALTER TABLE tasks ADD COLUMN completion_count INTEGER DEFAULT 0;
ALTER TABLE tasks ADD COLUMN success_count INTEGER DEFAULT 0;
ALTER TABLE tasks ADD COLUMN failure_count INTEGER DEFAULT 0;
ALTER TABLE tasks ADD COLUMN last_completed_at TIMESTAMPTZ;
ALTER TABLE tasks ADD COLUMN avg_completion_time_seconds INTEGER;
ALTER TABLE tasks ADD COLUMN reward_metadata JSONB; -- { type: 'money' | 'privilege' | 'points', value: string, custom: {...} }

-- Computed field (virtual in queries)
-- success_rate = success_count / completion_count

New Table: Task Completion History

CREATE TABLE task_completions (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
task_id UUID NOT NULL REFERENCES tasks(id) ON DELETE CASCADE,
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
group_id UUID NOT NULL REFERENCES groups(id) ON DELETE CASCADE,

-- Completion metadata
completed_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
success BOOLEAN NOT NULL, -- true = task succeeded, false = failed/abandoned
completion_time_seconds INTEGER, -- time from created_at to completed_at

-- Context
reward_given BOOLEAN DEFAULT FALSE, -- was reward actually delivered?
reward_metadata JSONB, -- copy of task.reward_metadata at completion time

-- Performance annotations (optional, added by user or AI)
difficulty_rating INTEGER CHECK (difficulty_rating BETWEEN 1 AND 5), -- 1=easy, 5=hard
motivation_rating INTEGER CHECK (motivation_rating BETWEEN 1 AND 5), -- how motivated was user?
notes TEXT, -- free-form feedback

-- Marketplace
sellable BOOLEAN DEFAULT TRUE, -- user consent to include in marketplace data
sold_at TIMESTAMPTZ, -- when this data point was sold
morphcoin_earned DECIMAL(18, 8), -- MorphCoin earned from selling this data

created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE INDEX idx_task_completions_task ON task_completions(task_id);
CREATE INDEX idx_task_completions_user ON task_completions(user_id);
CREATE INDEX idx_task_completions_group ON task_completions(group_id);
CREATE INDEX idx_task_completions_sellable ON task_completions(sellable) WHERE sellable = TRUE;
CREATE INDEX idx_task_completions_completed_at ON task_completions(completed_at DESC);

New Table: MorphCoin Wallet

CREATE TABLE morphcoin_wallets (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
user_id UUID NOT NULL UNIQUE REFERENCES users(id) ON DELETE CASCADE,
group_id UUID REFERENCES groups(id) ON DELETE CASCADE, -- NULL = personal wallet

balance DECIMAL(18, 8) NOT NULL DEFAULT 0.0 CHECK (balance >= 0),
total_earned DECIMAL(18, 8) NOT NULL DEFAULT 0.0,
total_spent DECIMAL(18, 8) NOT NULL DEFAULT 0.0,

created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE INDEX idx_morphcoin_wallets_user ON morphcoin_wallets(user_id);

New Table: MorphCoin Transactions

CREATE TABLE morphcoin_transactions (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
wallet_id UUID NOT NULL REFERENCES morphcoin_wallets(id) ON DELETE CASCADE,

-- Transaction details
type VARCHAR(50) NOT NULL, -- 'earn_data_sale', 'earn_task_completion', 'spend_feature_unlock', 'spend_marketplace_purchase', 'transfer'
amount DECIMAL(18, 8) NOT NULL, -- positive = credit, negative = debit
balance_after DECIMAL(18, 8) NOT NULL,

-- References
task_completion_id UUID REFERENCES task_completions(id) ON DELETE SET NULL,

-- Description
description TEXT NOT NULL,
metadata JSONB, -- { buyer_id, listing_id, feature_unlocked, etc. }

created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE INDEX idx_morphcoin_transactions_wallet ON morphcoin_transactions(wallet_id);
CREATE INDEX idx_morphcoin_transactions_created_at ON morphcoin_transactions(created_at DESC);

API Endpoints

Task Rewards

POST /api/tasks/{task_id}/complete Mark task as complete and record completion data.

Request:

{
"success": true,
"reward_given": true,
"difficulty_rating": 3,
"motivation_rating": 4,
"notes": "Finished homework 10 min early, reward was extra iPad time",
"sellable": true
}

Response:

{
"task": {
"id": "...",
"status": "completed",
"completion_count": 5,
"success_count": 4,
"success_rate": 0.8,
"reward": true
},
"completion": {
"id": "...",
"completed_at": "2026-02-14T...",
"success": true,
"completion_time_seconds": 3600
},
"morphcoin_earned": 0.5
}

GET /api/tasks/{task_id}/history Get completion history for a task.

Response:

{
"task_id": "...",
"total_completions": 5,
"success_rate": 0.8,
"avg_completion_time": 3200,
"completions": [
{
"id": "...",
"completed_at": "2026-02-14T...",
"success": true,
"reward_given": true,
"difficulty_rating": 3,
"completion_time_seconds": 3600
}
]
}

GET /api/tasks/analytics Get aggregate task analytics for user/group.

Query params: user_id, group_id, space_id, start_date, end_date

Response:

{
"total_tasks": 50,
"completed_tasks": 42,
"success_rate": 0.85,
"avg_completion_time": 2800,
"reward_effectiveness": {
"with_reward": { "success_rate": 0.9, "avg_time": 2400 },
"without_reward": { "success_rate": 0.75, "avg_time": 3200 }
},
"top_motivators": [
{ "reward_type": "money", "success_rate": 0.92 },
{ "reward_type": "privilege", "success_rate": 0.88 }
]
}

MorphCoin Wallet

GET /api/morphcoin/wallet Get user's MorphCoin wallet.

Response:

{
"balance": 12.5,
"total_earned": 45.0,
"total_spent": 32.5,
"pending_earnings": 2.3
}

GET /api/morphcoin/transactions Get transaction history.

Response:

{
"transactions": [
{
"id": "...",
"type": "earn_data_sale",
"amount": 0.5,
"balance_after": 12.5,
"description": "Sold task completion data (5 points)",
"created_at": "2026-02-14T..."
}
]
}

POST /api/morphcoin/marketplace/list List task completion data for sale.

Request:

{
"completion_ids": ["...", "..."],
"price_per_point": 0.1,
"anonymize": true
}

GET /api/morphcoin/marketplace/listings Browse data listings (for buyers).

Response:

{
"listings": [
{
"id": "...",
"data_type": "task_completions",
"count": 100,
"category": "education/homework",
"price_per_point": 0.1,
"total_price": 10.0,
"anonymized": true,
"preview": {
"success_rate": 0.85,
"reward_types": ["money", "privilege"],
"avg_completion_time": 3200
}
}
]
}

Frontend UI

Task Detail Enhancements

Add to CreateTaskDialog and TaskDetail:

// New fields
<Label>
<Checkbox checked={reward} onChange={setReward} />
This task has a reward
</Label>

{reward && (
<div>
<Label>Reward Type</Label>
<Select value={rewardType} onChange={setRewardType}>
<option value="money">Money</option>
<option value="privilege">Privilege (screen time, outing, etc.)</option>
<option value="points">Points</option>
<option value="custom">Custom</option>
</Select>

<Label>Reward Value</Label>
<Input
placeholder="e.g., $5, 30 min iPad time, 100 points"
value={rewardValue}
onChange={setRewardValue}
/>
</div>
)}

Task Completion Dialog

When user marks task complete, show dialog:

<Dialog title="Task Completed! 🎉">
<p>Great job on completing: {task.title}</p>

<Label>Was this task successful?</Label>
<RadioGroup value={success}>
<Radio value={true}>Yes, completed successfully</Radio>
<Radio value={false}>No, gave up or failed</Radio>
</RadioGroup>

{task.reward && (
<>
<Label>Was the reward given?</Label>
<RadioGroup value={rewardGiven}>
<Radio value={true}>Yes, reward delivered</Radio>
<Radio value={false}>No, reward skipped</Radio>
</RadioGroup>
</>
)}

<Label>How difficult was this task?</Label>
<StarRating value={difficulty} max={5} />

<Label>How motivated were you?</Label>
<StarRating value={motivation} max={5} />

<Label>Notes (optional)</Label>
<Textarea placeholder="Any feedback about this task?" />

<Checkbox checked={sellable}>
Allow Morphee to anonymize and sell this data for {earnedMorphcoin} MorphCoin
</Checkbox>

<Button onClick={handleComplete}>Submit & Earn MorphCoin</Button>
</Dialog>

Task History View

Add tab to TaskDetail:

<Tabs>
<Tab label="Details">...</Tab>
<Tab label="History">
<TaskHistoryChart
completions={history}
successRate={task.success_rate}
avgTime={task.avg_completion_time}
/>

<h3>Completion History</h3>
{history.map(c => (
<HistoryItem
key={c.id}
date={c.completed_at}
success={c.success}
rewardGiven={c.reward_given}
difficulty={c.difficulty_rating}
time={c.completion_time_seconds}
notes={c.notes}
morphcoinEarned={c.morphcoin_earned}
/>
))}
</Tab>
<Tab label="Analytics">
<RewardEffectivenessChart data={analytics.reward_effectiveness} />
<CompletionTimeChart data={analytics.avg_completion_time} />
</Tab>
</Tabs>

MorphCoin Wallet Widget

Add to Header or Settings:

<WalletBadge>
<CoinIcon />
{wallet.balance.toFixed(2)} MC
<Popover>
<WalletDetails>
<p>Balance: {wallet.balance} MC</p>
<p>Total Earned: {wallet.total_earned} MC</p>
<p>Pending: {wallet.pending_earnings} MC</p>
<Button onClick={() => navigate('/marketplace')}>
Browse Marketplace
</Button>
<Button onClick={() => navigate('/wallet/transactions')}>
Transaction History
</Button>
</WalletDetails>
</Popover>
</WalletBadge>

Marketplace Page

New route: /marketplace

<MarketplacePage>
<Tabs>
<Tab label="Buy Data">
<DataListings>
{listings.map(listing => (
<ListingCard
key={listing.id}
dataType={listing.data_type}
count={listing.count}
price={listing.total_price}
preview={listing.preview}
onPurchase={() => handlePurchase(listing.id)}
/>
))}
</DataListings>
</Tab>

<Tab label="Sell Data">
<YourData>
<p>You have {sellableCompletions} task completions ready to sell</p>
<p>Estimated earnings: {estimatedEarnings} MC</p>
<Button onClick={handleListData}>List All for Sale</Button>
</YourData>
</Tab>

<Tab label="Your Listings">
<ActiveListings>...</ActiveListings>
</Tab>
</Tabs>
</MarketplacePage>

Backend Implementation

Services

File: backend/tasks/rewards_service.py

from datetime import datetime
from typing import Optional
from uuid import UUID
from pydantic import BaseModel

class TaskCompletionCreate(BaseModel):
success: bool
reward_given: bool = False
difficulty_rating: Optional[int] = None
motivation_rating: Optional[int] = None
notes: Optional[str] = None
sellable: bool = True

class RewardsService:
def __init__(self, db_pool):
self.db = db_pool

async def complete_task(
self,
task_id: UUID,
user_id: UUID,
group_id: UUID,
completion: TaskCompletionCreate
) -> dict:
"""Mark task complete and record performance data."""
async with self.db.acquire() as conn:
async with conn.transaction():
# Get task
task = await conn.fetchrow(
"SELECT * FROM tasks WHERE id = $1 AND group_id = $2",
task_id, group_id
)
if not task:
raise ValueError("Task not found")

# Calculate completion time
completion_time = int((datetime.utcnow() - task['created_at']).total_seconds())

# Create completion record
completion_record = await conn.fetchrow("""
INSERT INTO task_completions (
task_id, user_id, group_id, success,
completion_time_seconds, reward_given,
reward_metadata, difficulty_rating,
motivation_rating, notes, sellable
) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)
RETURNING *
""",
task_id, user_id, group_id, completion.success,
completion_time, completion.reward_given,
task['reward_metadata'], completion.difficulty_rating,
completion.motivation_rating, completion.notes,
completion.sellable
)

# Update task aggregate stats
await conn.execute("""
UPDATE tasks SET
completion_count = completion_count + 1,
success_count = success_count + $1,
failure_count = failure_count + $2,
last_completed_at = NOW(),
avg_completion_time_seconds = (
COALESCE(avg_completion_time_seconds, 0) * completion_count +
$3
) / (completion_count + 1),
status = 'completed',
updated_at = NOW()
WHERE id = $4
""",
1 if completion.success else 0,
0 if completion.success else 1,
completion_time,
task_id
)

# Award MorphCoin for sellable completion
morphcoin_earned = 0.0
if completion.sellable:
# Base: 0.5 MC per completion
# Bonus: +0.1 MC if ratings provided
# Bonus: +0.2 MC if notes provided
morphcoin_earned = 0.5
if completion.difficulty_rating and completion.motivation_rating:
morphcoin_earned += 0.1
if completion.notes and len(completion.notes) > 20:
morphcoin_earned += 0.2

await self._award_morphcoin(
user_id, group_id, morphcoin_earned,
'earn_task_completion',
f"Task completion: {task['title']}",
completion_record['id']
)

# Get updated task
updated_task = await conn.fetchrow(
"SELECT * FROM tasks WHERE id = $1",
task_id
)

return {
'task': dict(updated_task),
'completion': dict(completion_record),
'morphcoin_earned': morphcoin_earned
}

async def _award_morphcoin(
self,
user_id: UUID,
group_id: Optional[UUID],
amount: float,
transaction_type: str,
description: str,
completion_id: Optional[UUID] = None
):
"""Award MorphCoin to user's wallet."""
async with self.db.acquire() as conn:
async with conn.transaction():
# Get or create wallet
wallet = await conn.fetchrow("""
INSERT INTO morphcoin_wallets (user_id, group_id)
VALUES ($1, $2)
ON CONFLICT (user_id) DO UPDATE SET updated_at = NOW()
RETURNING *
""", user_id, group_id)

# Update balance
new_balance = float(wallet['balance']) + amount
await conn.execute("""
UPDATE morphcoin_wallets SET
balance = $1,
total_earned = total_earned + $2,
updated_at = NOW()
WHERE id = $3
""", new_balance, amount, wallet['id'])

# Record transaction
await conn.execute("""
INSERT INTO morphcoin_transactions (
wallet_id, type, amount, balance_after,
task_completion_id, description
) VALUES ($1, $2, $3, $4, $5, $6)
""",
wallet['id'], transaction_type, amount, new_balance,
completion_id, description
)

async def get_task_history(self, task_id: UUID, group_id: UUID) -> dict:
"""Get completion history for a task."""
async with self.db.acquire() as conn:
task = await conn.fetchrow(
"SELECT * FROM tasks WHERE id = $1 AND group_id = $2",
task_id, group_id
)
if not task:
raise ValueError("Task not found")

completions = await conn.fetch("""
SELECT * FROM task_completions
WHERE task_id = $1
ORDER BY completed_at DESC
""", task_id)

return {
'task_id': task_id,
'total_completions': task['completion_count'],
'success_rate': (
task['success_count'] / task['completion_count']
if task['completion_count'] > 0 else 0
),
'avg_completion_time': task['avg_completion_time_seconds'],
'completions': [dict(c) for c in completions]
}

async def get_analytics(
self,
user_id: Optional[UUID] = None,
group_id: Optional[UUID] = None,
space_id: Optional[UUID] = None,
start_date: Optional[datetime] = None,
end_date: Optional[datetime] = None
) -> dict:
"""Get aggregate task analytics."""
# Complex analytics query - compute success rates with/without rewards
async with self.db.acquire() as conn:
# Total tasks
total_tasks = await conn.fetchval("""
SELECT COUNT(*) FROM tasks
WHERE ($1::uuid IS NULL OR user_id = $1)
AND ($2::uuid IS NULL OR group_id = $2)
AND ($3::uuid IS NULL OR space_id = $3)
""", user_id, group_id, space_id)

# Completed tasks
completed_tasks = await conn.fetchval("""
SELECT COUNT(*) FROM tasks
WHERE status = 'completed'
AND ($1::uuid IS NULL OR user_id = $1)
AND ($2::uuid IS NULL OR group_id = $2)
AND ($3::uuid IS NULL OR space_id = $3)
""", user_id, group_id, space_id)

# Success rate with/without rewards
with_reward = await conn.fetchrow("""
SELECT
AVG(CASE WHEN success_count > 0 THEN success_count::float / completion_count ELSE 0 END) as success_rate,
AVG(avg_completion_time_seconds) as avg_time
FROM tasks
WHERE reward = TRUE
AND completion_count > 0
AND ($1::uuid IS NULL OR user_id = $1)
AND ($2::uuid IS NULL OR group_id = $2)
AND ($3::uuid IS NULL OR space_id = $3)
""", user_id, group_id, space_id)

without_reward = await conn.fetchrow("""
SELECT
AVG(CASE WHEN success_count > 0 THEN success_count::float / completion_count ELSE 0 END) as success_rate,
AVG(avg_completion_time_seconds) as avg_time
FROM tasks
WHERE reward = FALSE
AND completion_count > 0
AND ($1::uuid IS NULL OR user_id = $1)
AND ($2::uuid IS NULL OR group_id = $2)
AND ($3::uuid IS NULL OR space_id = $3)
""", user_id, group_id, space_id)

return {
'total_tasks': total_tasks,
'completed_tasks': completed_tasks,
'success_rate': (
completed_tasks / total_tasks if total_tasks > 0 else 0
),
'reward_effectiveness': {
'with_reward': {
'success_rate': float(with_reward['success_rate'] or 0),
'avg_time': int(with_reward['avg_time'] or 0)
},
'without_reward': {
'success_rate': float(without_reward['success_rate'] or 0),
'avg_time': int(without_reward['avg_time'] or 0)
}
}
}

File: backend/tasks/morphcoin_service.py

class MorphCoinService:
def __init__(self, db_pool):
self.db = db_pool

async def get_wallet(self, user_id: UUID) -> dict:
"""Get user's MorphCoin wallet."""
async with self.db.acquire() as conn:
wallet = await conn.fetchrow("""
SELECT * FROM morphcoin_wallets WHERE user_id = $1
""", user_id)

if not wallet:
# Create wallet if doesn't exist
wallet = await conn.fetchrow("""
INSERT INTO morphcoin_wallets (user_id)
VALUES ($1)
RETURNING *
""", user_id)

# Get pending earnings (sellable completions not yet sold)
pending = await conn.fetchval("""
SELECT COUNT(*) * 0.5 FROM task_completions
WHERE user_id = $1 AND sellable = TRUE AND sold_at IS NULL
""", user_id)

return {
'balance': float(wallet['balance']),
'total_earned': float(wallet['total_earned']),
'total_spent': float(wallet['total_spent']),
'pending_earnings': float(pending or 0)
}

async def list_data_for_sale(
self,
user_id: UUID,
completion_ids: list[UUID],
price_per_point: float,
anonymize: bool = True
) -> str:
"""List task completions for sale in marketplace."""
# Implementation for marketplace listing
# Returns listing_id
pass

async def purchase_data(
self,
buyer_id: UUID,
listing_id: UUID
) -> dict:
"""Purchase data listing."""
# Deduct MorphCoin from buyer
# Transfer to seller
# Mark completions as sold
# Return purchased data
pass

API Routes

File: backend/api/tasks.py (add new routes)

from backend.tasks.rewards_service import RewardsService, TaskCompletionCreate

@router.post("/tasks/{task_id}/complete")
async def complete_task(
task_id: UUID,
completion: TaskCompletionCreate,
user: User = Depends(get_current_user)
):
"""Mark task as complete and record performance data."""
rewards_service = RewardsService(db_pool)
result = await rewards_service.complete_task(
task_id, user.id, user.group_id, completion
)
return result

@router.get("/tasks/{task_id}/history")
async def get_task_history(
task_id: UUID,
user: User = Depends(get_current_user)
):
"""Get completion history for a task."""
rewards_service = RewardsService(db_pool)
history = await rewards_service.get_task_history(task_id, user.group_id)
return history

@router.get("/tasks/analytics")
async def get_task_analytics(
user_id: Optional[UUID] = None,
space_id: Optional[UUID] = None,
start_date: Optional[datetime] = None,
end_date: Optional[datetime] = None,
user: User = Depends(get_current_user)
):
"""Get aggregate task analytics."""
rewards_service = RewardsService(db_pool)
analytics = await rewards_service.get_analytics(
user_id=user_id or user.id,
group_id=user.group_id,
space_id=space_id,
start_date=start_date,
end_date=end_date
)
return analytics

File: backend/api/morphcoin.py (new file)

from fastapi import APIRouter, Depends
from backend.tasks.morphcoin_service import MorphCoinService

router = APIRouter(prefix="/morphcoin", tags=["morphcoin"])

@router.get("/wallet")
async def get_wallet(user: User = Depends(get_current_user)):
service = MorphCoinService(db_pool)
return await service.get_wallet(user.id)

@router.get("/transactions")
async def get_transactions(
limit: int = 50,
offset: int = 0,
user: User = Depends(get_current_user)
):
service = MorphCoinService(db_pool)
return await service.get_transactions(user.id, limit, offset)

@router.post("/marketplace/list")
async def list_data(
listing: MarketplaceListingCreate,
user: User = Depends(get_current_user)
):
service = MorphCoinService(db_pool)
return await service.list_data_for_sale(
user.id, listing.completion_ids,
listing.price_per_point, listing.anonymize
)

@router.get("/marketplace/listings")
async def get_listings(
category: Optional[str] = None,
limit: int = 20,
user: User = Depends(get_current_user)
):
service = MorphCoinService(db_pool)
return await service.get_marketplace_listings(category, limit)

AI Learning Integration

How AI learns from this data:

  1. Task Success Predictor: Train model to predict success likelihood given task attributes (title, description, reward, user history)

  2. Reward Optimizer: Learn which reward types maximize success rate for each user persona (kids vs adults, subjects, time of day)

  3. Timing Optimizer: Predict optimal task scheduling based on completion patterns

  4. Personalized Suggestions: "This task is similar to one you completed with 90% success. Would you like me to add the same reward?"

File: backend/memory/task_learning.py

class TaskLearningService:
"""AI learning from task completion data."""

async def predict_success_probability(
self,
task_description: str,
reward_type: Optional[str],
user_id: UUID
) -> float:
"""Predict likelihood of task success."""
# Get user's historical data
# Extract features (task type, reward type, time of day, etc.)
# Query LLM with RAG context from similar tasks
# Return probability 0.0-1.0
pass

async def suggest_optimal_reward(
self,
task_description: str,
user_id: UUID
) -> dict:
"""Suggest reward type most likely to maximize success."""
# Analyze user's completion history
# Find reward types with highest success rates
# Return suggestion with explanation
pass

async def generate_insights(
self,
group_id: UUID
) -> list[str]:
"""Generate natural language insights from task data."""
# "Your kids complete homework 40% faster with screen time rewards"
# "Math tasks have 25% lower success rate than reading tasks"
# "Tasks assigned before 3pm have 60% higher completion rate"
pass

AI Actions (add to LLMIntegration or create TaskAnalysisIntegration):

  • analyze_task_patterns: "What patterns do you see in my kids' task completion?"
  • suggest_reward: "What reward should I offer for this homework task?"
  • predict_success: "Will my son likely complete this task if I offer $5 reward?"
  • optimize_schedule: "When should I schedule this task for maximum success?"

Marketplace Economics

MorphCoin Earning Rates:

  • Base task completion (sellable): 0.5 MC
  • With ratings: +0.1 MC
  • With detailed notes (>20 chars): +0.2 MC
  • High-quality data (complete metadata): +0.3 MC
  • Total per completion: 0.5 - 1.1 MC

MorphCoin Spending:

  • Unlock premium features: 5-50 MC
  • Advanced analytics: 10 MC/month
  • AI insights report: 2 MC
  • Custom skill creation: 5 MC
  • Priority support: 20 MC/month

Data Pricing (marketplace):

  • Education data: 0.1-0.2 MC per completion
  • Corporate productivity data: 0.5-1.0 MC per completion
  • Parenting/family data: 0.05-0.15 MC per completion

Buyer Personas:

  • EdTech companies: Buy education task data to train AI tutors
  • HR tech: Buy productivity/work task data for workforce analytics
  • Parenting apps: Buy family task data for behavior insights
  • Academic researchers: Buy anonymized data for studies
  • AI companies: Buy all data for RL training

Privacy & GDPR Compliance

Opt-in by default: All task completions default to sellable=true, but users can toggle per-completion or globally in settings.

Anonymization: Before sale, strip PII:

  • Remove user_id, group_id → replace with synthetic IDs
  • Remove notes if contains names/places
  • Remove task title/description → replace with category labels
  • Keep: success/failure, ratings, timing, reward type

Data deletion: On account deletion, cascade delete all task_completions and morphcoin_transactions. Sold data already in buyer's hands cannot be recalled (disclosed in ToS).

GDPR Article 22: Automated decision-making using this data requires explicit consent. Users must consent to "AI uses my task data to make suggestions" separately from "sell my data".

Children's data: Users under 13 cannot sell data (COPPA). Parents can sell children's data with consent checkbox: "I consent to anonymize and sell my child's task completion data."


Testing Strategy

Backend tests (backend/tests/test_rewards.py):

@pytest.mark.asyncio
async def test_complete_task_with_reward():
# Create task with reward
# Complete it successfully
# Assert completion_count incremented
# Assert success_count incremented
# Assert MorphCoin awarded
# Assert completion record created

@pytest.mark.asyncio
async def test_task_success_rate_calculation():
# Complete task 3 times (2 success, 1 failure)
# Assert success_rate = 0.666...

@pytest.mark.asyncio
async def test_morphcoin_wallet_balance():
# Award 5 MC
# Spend 2 MC
# Assert balance = 3 MC
# Assert total_earned = 5 MC
# Assert total_spent = 2 MC

Frontend tests (frontend/src/__tests__/rewards.test.tsx):

describe('Task Completion Dialog', () => {
it('shows reward fields when task has reward', () => {
render(<CompletionDialog task={taskWithReward} />)
expect(screen.getByText(/was the reward given/i)).toBeInTheDocument()
})

it('calculates MorphCoin earned correctly', () => {
// Base 0.5 + ratings 0.1 + notes 0.2 = 0.8 MC
render(<CompletionDialog task={task} />)
fillRatings()
fillNotes('This was a great task!')
expect(screen.getByText(/earn 0.8 MC/i)).toBeInTheDocument()
})
})

Migration Path

Phase 1 (v1.1, 6-8 hours):

  • Add database columns (migration)
  • Implement complete_task API
  • Add completion dialog to frontend
  • Basic MorphCoin wallet display
  • No marketplace yet (just accumulate MC)

Phase 2 (v1.2, 8-10 hours):

  • Task history view
  • Analytics dashboard
  • AI insights ("your kids work better with money rewards")
  • Wallet transaction history

Phase 3 (v1.3, 12-16 hours):

  • Marketplace listing/browsing
  • Data purchase flow
  • Anonymization pipeline
  • Buyer API (for external integration)

Phase 4 (v1.4+):

  • Advanced AI learning (success predictor)
  • Reward optimizer
  • Automated daily insights
  • Premium feature unlocks with MC

Success Metrics

User engagement:

  • % of tasks with rewards enabled
  • % of completions with ratings/notes (data quality)
  • Avg completions per user per week
  • Wallet balance distribution

Data marketplace:

  • % of users who list data for sale
  • Avg MC earned per user per month
  • Number of buyers
  • Total data points sold

AI learning:

  • Success prediction accuracy (target: >70%)
  • Reward suggestion acceptance rate
  • User satisfaction with AI insights

Open Questions

  1. MorphCoin blockchain or centralized? Start centralized (faster), migrate to blockchain later for true ownership?

  2. Data pricing: Fixed or dynamic? Fixed per-point pricing or market-driven (supply/demand)?

  3. Reward validation: How to verify reward was actually given? Honor system or require proof (photo)?

  4. Bulk data export: Should users be able to export all their task data for personal use (GDPR right)?

  5. Group vs personal wallet: Should groups have shared wallets for family rewards?

  6. Premium features: Which features should cost MorphCoin? Analytics? AI suggestions? Storage?


Recommendation: v1.0 or v1.1?

My recommendation: Implement in v1.1 (after v1.0 launch)

Why defer to v1.1:

  1. Scope: 6-8 hours minimum for Phase 1 (database + API + basic UI). Conflicts with "tomorrow" v1.0 deadline.

  2. Data accumulation: Marketplace needs data to sell. Need a few weeks of tasks completed before marketplace is useful.

  3. Core product first: v1.0 should prove core value (chat-first AI agent for families). Rewards/marketplace is a growth feature.

  4. Testing: This feature needs real-world validation. Ship v1.0, gather feedback, then add rewards based on what users actually want.

But: If you want rewards in v1.0, we can do a minimal implementation (just reward flag + completion tracking, no MorphCoin) in 2-3 hours, then expand in v1.1.

Next step: Should I:

  1. Ship v1.0 today (Option A from earlier), then implement full rewards system in v1.1 next week?
  2. Polish v1.0 tomorrow (Option B), add minimal rewards (just tracking, no coins), ship EOD tomorrow?
  3. Full rewards in v1.0 (delay launch 1-2 days, implement complete Phase 1 rewards)?

Tell me your preference and I'll proceed! 🚀