build(agent): new-agents#a6e6ec iteration
This commit is contained in:
parent
c1c701b0b6
commit
1c964184ee
|
|
@ -43,3 +43,6 @@ How to contribute
|
|||
- All changes should be backed by tests.
|
||||
|
||||
This repo ships a production-like MVP rather than a toy example. Expect incremental exposure of domain adapters and more rigorous conformance tests in future milestones.
|
||||
|
||||
## Migration and Evolution
|
||||
- Contract migration: The contract registry now supports migrating a contract from an older version to a newer version. This enables adapters to evolve data schemas over time while marking the legacy version as migrated. The old version will have a migrated_to field pointing to the new version, and the new version will register its updated schema. This helps maintain backward-compatibility during MVP-driven evolution of the canonical IR.
|
||||
|
|
|
|||
|
|
@ -40,3 +40,25 @@ class ContractRegistry:
|
|||
if not isinstance(required, (list, tuple)):
|
||||
return False
|
||||
return all(field in adapter_data for field in required)
|
||||
|
||||
def migrate_contract(self, name: str, old_version: str, new_version: str, new_schema: Dict[str, Any]) -> None:
|
||||
"""Migrate a contract from an old version to a new version.
|
||||
|
||||
- Mark the old_version as migrated_to new_version (if present).
|
||||
- Register the new_version with the provided new_schema.
|
||||
This enables simple, MVP-aligned contract evolution for adapters during the MVP lifecycle.
|
||||
"""
|
||||
# Ensure parent namespace exists
|
||||
self._store.setdefault(name, {})
|
||||
# Mark old version as migrated to new version if it exists
|
||||
if old_version in self._store.get(name, {}):
|
||||
self._store[name][old_version]["migrated_to"] = new_version
|
||||
# Register the new version with its schema
|
||||
self._store[name][new_version] = dict(new_schema)
|
||||
|
||||
def get_migration_target(self, name: str, version: str) -> Optional[str]:
|
||||
"""Return the version that this version migrated to, if any."""
|
||||
contract = self.get_contract(name, version)
|
||||
if contract is None:
|
||||
return None
|
||||
return contract.get("migrated_to")
|
||||
|
|
|
|||
|
|
@ -32,3 +32,17 @@ class TestContractRegistry(unittest.TestCase):
|
|||
reg.register_contract("LocalProblem", "1.0.0", {"required_fields": ["id", "objective"]})
|
||||
adapter_data = {"id": "lp-1"}
|
||||
self.assertFalse(reg.conformance_check("LocalProblem", "1.0.0", adapter_data))
|
||||
|
||||
def test_contract_migration(self):
|
||||
reg = ContractRegistry()
|
||||
reg.register_contract("LocalProblem", "1.0.0", {"required_fields": ["id"]})
|
||||
# Migrate to a new version with a richer schema
|
||||
reg.migrate_contract("LocalProblem", "1.0.0", "1.1.0", {"required_fields": ["id", "objective"]})
|
||||
|
||||
# New version should exist
|
||||
self.assertEqual(reg.get_contract("LocalProblem", "1.1.0"), {"required_fields": ["id", "objective"]})
|
||||
|
||||
# Old version should be marked as migrated to the new version
|
||||
old = reg.get_contract("LocalProblem", "1.0.0")
|
||||
self.assertIsNotNone(old)
|
||||
self.assertEqual(old.get("migrated_to"), "1.1.0")
|
||||
|
|
|
|||
Loading…
Reference in New Issue