Hosted service offline; see undercurrentholdings.com/status
Deployment

AEGIS Migration Guide

Version: 1.0.0 | Updated: 2026-02-09 | Status: Active

Version: 1.0.0 | Updated: 2026-02-09 | Status: Active

This guide covers upgrading AEGIS versions, migrating parameter schemas, recalibrating thresholds, and handling workflow state migrations.


1. Parameter Schema Migration

Schema Versioning

schema/interface-contract.yaml is the authoritative source for all frozen parameters. The schema version is tracked in the file's version field.

Migration Procedure

  1. Compare schemas: Diff old and new interface-contract.yaml

    git diff guardrail-v1.1-freeze..HEAD -- schema/interface-contract.yaml
  2. Identify changes: New parameters get defaults automatically. Modified parameters require review.

  3. Validate config: Test your custom config against the new schema

    aegis validate-config <your-config.yaml>
  4. Rollback plan: Keep a tagged backup of the previous frozen state

    git tag guardrail-v{X.Y}-freeze -m "Freeze guardrail params at v{X.Y}"

Parameter Change Categories

Change TypeImpactAction Required
New parameter with defaultNoneBackward compatible
Default value changePotentialReview + test
Parameter removalBreakingRemove from custom config
Parameter renameBreakingUpdate custom config

2. Parameter Recalibration

When to Recalibrate

  • KL divergence drift detection triggers sustained warnings (tau_warning exceeded)
  • Business requirements change (risk tolerance shift)
  • Model performance degrades over time
  • Calibrator actor proposes threshold adjustments

Recalibration via Calibrator Actor

The Calibrator actor (src/actors/calibrator.py) provides a structured workflow for threshold tuning:

from actors.calibrator import Calibrator
from engine.drift import DriftMonitor
from engine.bayesian import BayesianPosterior

calibrator = Calibrator(
    actor_id="calibrator-1",
    drift_monitor=drift_monitor,
    bayesian_posterior=posterior,
)

# 1. Propose new thresholds based on observed data
proposal = calibrator.propose_calibration(
    parameter="tau_warning",
    new_value=0.35,
    justification="Sustained drift above current threshold",
)

# 2. Approval gate (requires human approval)
calibrator.approve(proposal.proposal_id, approver_id="risk-lead")

# 3. Apply calibrated thresholds
calibrator.apply_calibration(proposal.proposal_id)

Recognized Parameters

The Calibrator accepts changes to these 16 parameters (whitelist in _RECOGNIZED_PARAMETERS):

CategoryParameters
Gate thresholdsepsilon_R, epsilon_P, risk_trigger_factor, profit_trigger_factor, trigger_confidence_prob, novelty_threshold, complexity_floor, quality_min_score, utility_threshold
Novelty functionnovelty_N0, novelty_k
Drift detectiontau_warning, tau_critical
Bayesianprior_mean, prior_std, likelihood_std

Safety Constraints

  • Calibration proposals require APPROVED status before application
  • The _RECOGNIZED_PARAMETERS whitelist prevents modification of unrecognized parameters
  • Thread-safe via threading.Lock
  • All calibration events emit telemetry for audit trail

3. Workflow State Migration

Persistence Schema

AEGIS workflow state is stored via SQLAlchemy ORM models (src/workflows/persistence/models.py):

ModelPurposeKey Fields
WorkflowInstanceCore workflow stateworkflow_id, workflow_type, current_state, state_data (JSON)
WorkflowTransitionAudit trailfrom_state, to_state, triggered_by, hash (SHA-256 chain)
WorkflowCheckpointResume snapshotscheckpoint_data, hash (integrity)

Schema version: 1.0.0

Upgrade Procedure

Current approach:

  1. Export existing workflow data:

    from workflows.persistence.repository import WorkflowPersistence
    workflows = await repo.list_workflows(status="pending")
  2. Apply schema changes via SQL migration scripts

  3. Re-import workflows with updated schema

Roadmap: Alembic migration framework is planned for automatic schema versioning (alembic upgrade head). Until then, use the manual procedure above.

Rollback Procedure

If a migration fails or the new version exhibits issues:

  1. Serialization backup (before migration):

    import json
    from workflows.persistence.repository import WorkflowPersistence
    
    workflows = await repo.list_workflows()
    backup = [w.to_dict() for w in workflows]
    with open("workflow-backup.json", "w") as f:
        json.dump(backup, f)
  2. Restore from backup:

    for data in backup:
        workflow = ProposalWorkflow.from_dict(data)
        await repo.save_checkpoint(workflow, actor_id="migration-rollback")
  3. Database point-in-time recovery: If using PostgreSQL with continuous archiving, restore to a point before the migration:

    # AWS RDS example
    aws rds restore-db-instance-to-point-in-time \
      --source-db-instance-identifier aegis-db \
      --target-db-instance-identifier aegis-db-restored \
      --restore-time "2026-03-05T12:00:00Z"
  4. Redeploy previous version: Roll back the container image or Lambda function to the pre-migration tag:

    git checkout guardrail-v{PREVIOUS}-freeze

Serialization

All workflows support to_dict() / from_dict() serialization:

# Export
data = workflow.to_dict()

# Import (handles timezone normalization via ensure_utc)
workflow = ProposalWorkflow.from_dict(data)

The shared ensure_utc() helper (src/workflows/serialization.py) normalizes timestamps across all three workflow types (proposal, consensus, override).

Data Safety

  • PII fields: 12 telemetry fields encrypted at rest via PIIEncryptionEnricher
  • Audit trail: Hash-chained transitions (SHA-256) for tamper detection
  • Encrypted fields: EncryptedField.value_type discriminator ("str", "bytes", "json") for lossless round-trips

Override Signatures (P5-1 / G133)

Two-key override signatures are now bound to role and signer id. Signers must sign workflow.role_message_hash(role, signer_id); a signature over the bare message_hash is rejected, and a PARTIAL override (one signature recorded) persisted before the change must be re-requested. See Signed Message (Role Binding).


4. Configuration Upgrade Path

AegisConfig Properties

AegisConfig is a frozen dataclass — instances are immutable after creation. This prevents parameter drift during a session.

from aegis_governance import AegisConfig

# Immutable: raises AttributeError
config = AegisConfig.default()
config.epsilon_R = 0.5  # AttributeError: cannot assign to field

Backward Compatibility

ScenarioBehavior
New parameters added to schemaGet default values automatically
Parameters removed from schemaRemove from custom YAML (no code change needed)
from_yaml() encounters unknown keysIgnored with log warning
from_dict() encounters unknown keysIgnored with log warning

Configuration Loading

AegisConfig.from_yaml() reads the parameters key with nested sections:

# Top-level parameters
parameters:
  epsilon_R: 0.01
  # Nested section
  novelty_gate:
    N0: 0.7
    k: 10.0
    output_threshold: 0.6
  # Nested section
  kl_drift:
    tau_warning: 0.3
    tau_critical: 0.5
    window_days: 30

Nested sections are mapped to flat AegisConfig fields via _NESTED_SECTIONS in src/config.py.


5. Version Compatibility Matrix

AEGIS Version Matrix

AEGIS VersionSchema VersionPython VersionsBreaking Changes
v1.0.0v1.1.13.9, 3.10, 3.11, 3.12First release

The v1.0.0 row is historical. Current releases support Python 3.10–3.12 (3.9 was dropped under G107); see Dependency Compatibility below.

Dependency Compatibility

DependencyMinimumRecommendedNotes
Python3.103.113.10 is minimum supported (requires-python = ">=3.10")
scipy1.7.01.12+Optional (engine group)
prometheus_client0.16.00.20+Optional (telemetry group)
SQLAlchemy2.0.522.0.x (<2.1.0)Optional (engine/persistence groups, mirrored in dev/all); capped below 2.1 until ROADMAP G127
pyyaml6.06.0+Optional (config group)
btclib2023.72023.7+Optional (crypto group)

6. Pre-Migration Checklist

  • Backup current config: cp schema/interface-contract.yaml schema/interface-contract.yaml.bak

  • Tag current state: git tag guardrail-v{X.Y}-freeze

  • Run test suite against new version: pytest tests/ -v --tb=short

  • Validate config against new schema: aegis validate-config <config.yaml>

  • Test in staging: Deploy new version to staging environment first

  • Verify audit trail continuity: Ensure hash chain remains valid after migration

    from workflows.persistence.durable import DurableWorkflowEngine
    # Verify hash chain integrity
    is_valid, message = engine.verify_audit_chain(workflow_id)
    assert is_valid, f"Audit chain broken: {message}"
  • Review the CHANGELOG / release notes: Check for breaking changes in the target version

  • Update monitoring: Ensure Prometheus rules match new metric names (if changed)


References

On this page