# Generated by Django 5.2.11 on 2026-02-15 00:14

import uuid

import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models

import core.models


class Migration(migrations.Migration):

    dependencies = [
        ('core', '0016_airequest_airesult_workspaceconversation_and_more'),
    ]

    operations = [
        migrations.RemoveField(
            model_name='airesult',
            name='risk_flags',
        ),
        migrations.RemoveField(
            model_name='airesult',
            name='summary_m3',
        ),
        migrations.RemoveField(
            model_name='memoryitem',
            name='type',
        ),
        migrations.AddField(
            model_name='airesult',
            name='interaction_signals',
            field=models.JSONField(blank=True, default=list, help_text="Structured positive/neutral/risk signals inferred for this run. Example item: {'label':'repair_attempt','valence':'positive','message_event_ids':[...]}."),
        ),
        migrations.AddField(
            model_name='airesult',
            name='user',
            field=models.ForeignKey(default=core.models.get_default_workspace_user_pk, help_text='Owner of this AI result row (required for restricted CRUD filtering).', on_delete=django.db.models.deletion.CASCADE, related_name='workspace_ai_results', to=settings.AUTH_USER_MODEL),
        ),
        migrations.AddField(
            model_name='airesult',
            name='working_summary',
            field=models.TextField(blank=True, default='', help_text='Conversation working summary generated for this run.'),
        ),
        migrations.AddField(
            model_name='memoryitem',
            name='memory_kind',
            field=models.CharField(choices=[('fact', 'Durable Fact/Preference'), ('state', 'Relationship State'), ('summary', 'Conversation Working Summary')], default=1, help_text='Memory kind: fact/state/summary.', max_length=16),
            preserve_default=False,
        ),
        migrations.AddField(
            model_name='messageevent',
            name='source_system',
            field=models.CharField(choices=[('signal', 'Signal'), ('xmpp', 'XMPP'), ('workspace', 'Workspace'), ('ai', 'AI')], default='signal', help_text='System that produced this event record.', max_length=32),
        ),
        migrations.AddField(
            model_name='messageevent',
            name='user',
            field=models.ForeignKey(default=core.models.get_default_workspace_user_pk, help_text='Owner of this message event row (required for restricted CRUD filtering).', on_delete=django.db.models.deletion.CASCADE, related_name='workspace_message_events', to=settings.AUTH_USER_MODEL),
        ),
        migrations.AddField(
            model_name='workspaceconversation',
            name='commitment_confidence',
            field=models.FloatField(default=0.0, help_text='Confidence in commitment scores (0.0-1.0).'),
        ),
        migrations.AddField(
            model_name='workspaceconversation',
            name='commitment_inbound_score',
            field=models.FloatField(blank=True, help_text='Estimated commitment score for counterpart -> user direction (0-100). Null while calibrating.', null=True),
        ),
        migrations.AddField(
            model_name='workspaceconversation',
            name='commitment_last_computed_at',
            field=models.DateTimeField(blank=True, help_text='Timestamp of the latest commitment computation.', null=True),
        ),
        migrations.AddField(
            model_name='workspaceconversation',
            name='commitment_outbound_score',
            field=models.FloatField(blank=True, help_text='Estimated commitment score for user -> counterpart direction (0-100). Null while calibrating.', null=True),
        ),
        migrations.AddField(
            model_name='workspaceconversation',
            name='last_ai_run_at',
            field=models.DateTimeField(blank=True, help_text='Last time any AIRequest finished for this conversation.', null=True),
        ),
        migrations.AddField(
            model_name='workspaceconversation',
            name='participant_feedback',
            field=models.JSONField(blank=True, default=dict, help_text="Per-person interaction feedback map keyed by person UUID. Example: {'<person_uuid>': {'state': 'withdrawing', 'note': 'short replies'}}."),
        ),
        migrations.AddField(
            model_name='workspaceconversation',
            name='stability_confidence',
            field=models.FloatField(default=0.0, help_text='Confidence in stability_score (0.0-1.0).'),
        ),
        migrations.AddField(
            model_name='workspaceconversation',
            name='stability_last_computed_at',
            field=models.DateTimeField(blank=True, help_text='Timestamp of the latest stability computation.', null=True),
        ),
        migrations.AddField(
            model_name='workspaceconversation',
            name='stability_sample_days',
            field=models.PositiveIntegerField(default=0, help_text='How many calendar days of data were used for stability.'),
        ),
        migrations.AddField(
            model_name='workspaceconversation',
            name='stability_sample_messages',
            field=models.PositiveIntegerField(default=0, help_text='How many messages were used to compute stability.'),
        ),
        migrations.AddField(
            model_name='workspaceconversation',
            name='stability_score',
            field=models.FloatField(blank=True, help_text='Relationship stability score (0-100). Null while calibrating.', null=True),
        ),
        migrations.AddField(
            model_name='workspaceconversation',
            name='stability_state',
            field=models.CharField(choices=[('calibrating', 'Calibrating'), ('stable', 'Stable'), ('watch', 'Watch'), ('fragile', 'Fragile')], default='calibrating', help_text='UI label for relationship stability, baseline-aware.', max_length=32),
        ),
        migrations.AlterField(
            model_name='airequest',
            name='conversation',
            field=models.ForeignKey(help_text='Conversation analyzed by this request.', on_delete=django.db.models.deletion.CASCADE, related_name='ai_requests', to='core.workspaceconversation'),
        ),
        migrations.AlterField(
            model_name='airequest',
            name='created_at',
            field=models.DateTimeField(auto_now_add=True, help_text='Request creation timestamp.'),
        ),
        migrations.AlterField(
            model_name='airequest',
            name='error',
            field=models.TextField(blank=True, default='', help_text="Error details when status='failed'."),
        ),
        migrations.AlterField(
            model_name='airequest',
            name='finished_at',
            field=models.DateTimeField(blank=True, help_text='Worker completion timestamp.', null=True),
        ),
        migrations.AlterField(
            model_name='airequest',
            name='id',
            field=models.UUIDField(default=uuid.uuid4, editable=False, help_text='Stable identifier for this AI request.', primary_key=True, serialize=False),
        ),
        migrations.AlterField(
            model_name='airequest',
            name='message_ids',
            field=models.JSONField(blank=True, default=list, help_text='Resolved ordered MessageEvent IDs included in this run.'),
        ),
        migrations.AlterField(
            model_name='airequest',
            name='operation',
            field=models.CharField(choices=[('summarise', 'Summarise'), ('draft_reply', 'Draft Reply'), ('critique', 'Critique'), ('repair', 'Repair'), ('extract_patterns', 'Extract Patterns'), ('memory_propose', 'Memory Propose'), ('state_detect', 'State Detect'), ('rewrite_style', 'Rewrite Style'), ('send_readiness', 'Send Readiness'), ('timeline_brief', 'Timeline Brief')], help_text='Requested AI operation type.', max_length=32),
        ),
        migrations.AlterField(
            model_name='airequest',
            name='policy_snapshot',
            field=models.JSONField(blank=True, default=dict, help_text='Effective manipulation/policy values captured at request time, so results remain auditable even if policies change later.'),
        ),
        migrations.AlterField(
            model_name='airequest',
            name='started_at',
            field=models.DateTimeField(blank=True, help_text='Worker start timestamp.', null=True),
        ),
        migrations.AlterField(
            model_name='airequest',
            name='status',
            field=models.CharField(choices=[('queued', 'Queued'), ('running', 'Running'), ('done', 'Done'), ('failed', 'Failed')], default='queued', help_text='Worker lifecycle state for this request.', max_length=16),
        ),
        migrations.AlterField(
            model_name='airequest',
            name='user',
            field=models.ForeignKey(help_text='User who initiated this request.', on_delete=django.db.models.deletion.CASCADE, related_name='workspace_ai_requests', to=settings.AUTH_USER_MODEL),
        ),
        migrations.AlterField(
            model_name='airequest',
            name='user_notes',
            field=models.TextField(blank=True, default='', help_text='Optional user intent/context notes injected into the prompt.'),
        ),
        migrations.AlterField(
            model_name='airequest',
            name='window_spec',
            field=models.JSONField(default=dict, help_text='Selection spec (last_n/since_ts/between_ts/include_attachments/etc). Should be dynamically resolved by available context/token budget.'),
        ),
        migrations.AlterField(
            model_name='airesult',
            name='ai_request',
            field=models.OneToOneField(help_text='Owning AI request for this result.', on_delete=django.db.models.deletion.CASCADE, related_name='result', to='core.airequest'),
        ),
        migrations.AlterField(
            model_name='airesult',
            name='citations',
            field=models.JSONField(blank=True, default=list, help_text='Referenced MessageEvent IDs supporting generated claims.'),
        ),
        migrations.AlterField(
            model_name='airesult',
            name='created_at',
            field=models.DateTimeField(auto_now_add=True, help_text='Result creation timestamp.'),
        ),
        migrations.AlterField(
            model_name='airesult',
            name='draft_replies',
            field=models.JSONField(blank=True, default=list, help_text='Draft reply candidates, typically with tone and rationale.'),
        ),
        migrations.AlterField(
            model_name='airesult',
            name='id',
            field=models.UUIDField(default=uuid.uuid4, editable=False, help_text='Stable identifier for this AI result payload.', primary_key=True, serialize=False),
        ),
        migrations.AlterField(
            model_name='airesult',
            name='memory_proposals',
            field=models.JSONField(blank=True, default=list, help_text='Proposed memory entries, typically requiring user approval.'),
        ),
        migrations.AlterField(
            model_name='memoryitem',
            name='content',
            field=models.JSONField(blank=True, default=dict, help_text='Structured memory payload (schema can evolve by type).'),
        ),
        migrations.AlterField(
            model_name='memoryitem',
            name='conversation',
            field=models.ForeignKey(help_text='Conversation scope this memory item belongs to.', on_delete=django.db.models.deletion.CASCADE, related_name='memory_items', to='core.workspaceconversation'),
        ),
        migrations.AlterField(
            model_name='memoryitem',
            name='created_at',
            field=models.DateTimeField(auto_now_add=True, help_text='Row creation timestamp.'),
        ),
        migrations.AlterField(
            model_name='memoryitem',
            name='id',
            field=models.UUIDField(default=uuid.uuid4, editable=False, help_text='Stable identifier for this memory item.', primary_key=True, serialize=False),
        ),
        migrations.AlterField(
            model_name='memoryitem',
            name='source_request',
            field=models.ForeignKey(blank=True, help_text='AIRequest that originated this memory, if any.', null=True, on_delete=django.db.models.deletion.SET_NULL, to='core.airequest'),
        ),
        migrations.AlterField(
            model_name='memoryitem',
            name='status',
            field=models.CharField(choices=[('proposed', 'Proposed'), ('active', 'Active'), ('deprecated', 'Deprecated')], default='proposed', help_text='Lifecycle state, especially for approval-gated memories.', max_length=16),
        ),
        migrations.AlterField(
            model_name='memoryitem',
            name='updated_at',
            field=models.DateTimeField(auto_now=True, help_text='Last update timestamp.'),
        ),
        migrations.AlterField(
            model_name='memoryitem',
            name='user',
            field=models.ForeignKey(help_text='Owner of the memory item.', on_delete=django.db.models.deletion.CASCADE, related_name='workspace_memory_items', to=settings.AUTH_USER_MODEL),
        ),
        migrations.AlterField(
            model_name='messageevent',
            name='attachments',
            field=models.JSONField(blank=True, default=list, help_text='Attachment metadata list associated with this message.'),
        ),
        migrations.AlterField(
            model_name='messageevent',
            name='conversation',
            field=models.ForeignKey(help_text='AI workspace conversation this message belongs to. This is not the transport-native thread object.', on_delete=django.db.models.deletion.CASCADE, related_name='events', to='core.workspaceconversation'),
        ),
        migrations.AlterField(
            model_name='messageevent',
            name='created_at',
            field=models.DateTimeField(auto_now_add=True, help_text='Row creation timestamp.'),
        ),
        migrations.AlterField(
            model_name='messageevent',
            name='direction',
            field=models.CharField(choices=[('in', 'Inbound'), ('out', 'Outbound')], help_text="Direction relative to workspace owner: 'in' from counterpart(s), 'out' from user/bot side.", max_length=8),
        ),
        migrations.AlterField(
            model_name='messageevent',
            name='id',
            field=models.UUIDField(default=uuid.uuid4, editable=False, help_text='Stable identifier for this message event.', primary_key=True, serialize=False),
        ),
        migrations.AlterField(
            model_name='messageevent',
            name='raw_payload_ref',
            field=models.JSONField(blank=True, default=dict, help_text='Raw source payload or reference pointer for audit/debug.'),
        ),
        migrations.AlterField(
            model_name='messageevent',
            name='sender_uuid',
            field=models.CharField(blank=True, db_index=True, default='', help_text='Source sender UUID/identifier for correlation.', max_length=255),
        ),
        migrations.AlterField(
            model_name='messageevent',
            name='text',
            field=models.TextField(blank=True, default='', help_text='Normalized message text body.'),
        ),
        migrations.AlterField(
            model_name='messageevent',
            name='ts',
            field=models.BigIntegerField(db_index=True, help_text='Event timestamp (unix ms) as reported by source_system.'),
        ),
        migrations.AlterField(
            model_name='personidentifier',
            name='service',
            field=models.CharField(choices=[('signal', 'Signal'), ('xmpp', 'XMPP'), ('instagram', 'Instagram')], max_length=255),
        ),
        migrations.AlterField(
            model_name='workspaceconversation',
            name='created_at',
            field=models.DateTimeField(auto_now_add=True, help_text='Row creation timestamp.'),
        ),
        migrations.AlterField(
            model_name='workspaceconversation',
            name='id',
            field=models.UUIDField(default=uuid.uuid4, editable=False, help_text='Stable identifier for this workspace conversation.', primary_key=True, serialize=False),
        ),
        migrations.AlterField(
            model_name='workspaceconversation',
            name='last_event_ts',
            field=models.BigIntegerField(blank=True, help_text='Latest message timestamp (unix ms) currently known.', null=True),
        ),
        migrations.AlterField(
            model_name='workspaceconversation',
            name='participants',
            field=models.ManyToManyField(blank=True, help_text='Resolved people participating in this conversation.', related_name='workspace_conversations', to='core.person'),
        ),
        migrations.AlterField(
            model_name='workspaceconversation',
            name='platform_thread_id',
            field=models.CharField(blank=True, default='', help_text='Platform-native thread/group identifier when available.', max_length=255),
        ),
        migrations.AlterField(
            model_name='workspaceconversation',
            name='platform_type',
            field=models.CharField(choices=[('signal', 'Signal'), ('xmpp', 'XMPP'), ('instagram', 'Instagram')], default='signal', help_text='Primary transport for this conversation (reuses SERVICE_CHOICES).', max_length=255),
        ),
        migrations.AlterField(
            model_name='workspaceconversation',
            name='title',
            field=models.CharField(blank=True, default='', help_text='Human-friendly label shown in the workspace sidebar.', max_length=255),
        ),
        migrations.AlterField(
            model_name='workspaceconversation',
            name='user',
            field=models.ForeignKey(help_text='Owner of this conversation workspace.', on_delete=django.db.models.deletion.CASCADE, related_name='workspace_conversations', to=settings.AUTH_USER_MODEL),
        ),
        migrations.CreateModel(
            name='AIResultSignal',
            fields=[
                ('id', models.UUIDField(default=uuid.uuid4, editable=False, help_text='Stable identifier for this result signal.', primary_key=True, serialize=False)),
                ('label', models.CharField(help_text="Short signal label, e.g. 'withdrawing', 'repair_attempt'.", max_length=128)),
                ('valence', models.CharField(choices=[('positive', 'Positive'), ('neutral', 'Neutral'), ('risk', 'Risk')], default='neutral', help_text='Signal polarity: positive, neutral, or risk.', max_length=16)),
                ('score', models.FloatField(blank=True, help_text='Optional model confidence/strength (0.0-1.0).', null=True)),
                ('rationale', models.TextField(blank=True, default='', help_text='Human-readable explanation for this signal.')),
                ('created_at', models.DateTimeField(auto_now_add=True, help_text='Row creation timestamp.')),
                ('ai_result', models.ForeignKey(help_text='AI result that produced this signal.', on_delete=django.db.models.deletion.CASCADE, related_name='signals', to='core.airesult')),
                ('message_event', models.ForeignKey(blank=True, help_text='Optional specific message event referenced by this signal.', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='ai_signals', to='core.messageevent')),
                ('user', models.ForeignKey(help_text='Owner of this signal row (required for restricted CRUD filtering).', on_delete=django.db.models.deletion.CASCADE, related_name='workspace_ai_result_signals', to=settings.AUTH_USER_MODEL)),
            ],
        ),
    ]
