From 8d794f1394f99bee4086da59a208bb46a6cad9b1 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Fri, 21 Aug 2026 13:05:57 -0700 Subject: [PATCH 1/7] test(migration): reject forged runtime evidence types --- .../tests/test_runtime_evidence_integrity.py | 129 ++++++++++++++++++ 1 file changed, 129 insertions(+) create mode 100644 packages/migration-adapter/tests/test_runtime_evidence_integrity.py diff --git a/packages/migration-adapter/tests/test_runtime_evidence_integrity.py b/packages/migration-adapter/tests/test_runtime_evidence_integrity.py new file mode 100644 index 000000000..8db72c523 --- /dev/null +++ b/packages/migration-adapter/tests/test_runtime_evidence_integrity.py @@ -0,0 +1,129 @@ +"""Adversarial runtime-type regressions for governed migration evidence.""" + +from __future__ import annotations + +from dataclasses import replace + +import pytest + +from orgmetra_migration_adapter import ( + MAXIMUM_BATCH_RECORDS, + MHTML_ETL_GATEWAY_REVISION, + MIGHTY_ETL_REVISION, + ContractViolation, + MigrationHandoffInput, + build_migration_handoff, +) + + +class ForgedEqualityText(str): + """Carry unsafe text while pretending to equal one reviewed constant.""" + + def __new__(cls, value: str, pretend: str) -> "ForgedEqualityText": + """Create forged text with the reviewed value it should impersonate.""" + instance = super().__new__(cls, value) + instance.pretend = pretend + return instance + + def __eq__(self, other: object) -> bool: + """Pretend to equal only the reviewed comparison value.""" + return other == self.pretend + + def __ne__(self, other: object) -> bool: + """Invert the forged equality result for inequality guards.""" + return not self.__eq__(other) + + def __hash__(self) -> int: + """Collide with the reviewed value for set-membership checks.""" + return hash(self.pretend) + + +class ForgedCount(int): + """Carry an oversized count while defeating numeric bound comparisons.""" + + def __le__(self, other: object) -> bool: + """Pretend never to violate the positive lower bound.""" + return False + + def __gt__(self, other: object) -> bool: + """Pretend never to exceed the reviewed batch upper bound.""" + return False + + +def _valid_input(**changes: object) -> MigrationHandoffInput: + """Return one minimal approved migration handoff input for adversarial tests.""" + evidence = MigrationHandoffInput( + tenant_record_id="10000000-0000-7000-8000-000000000001", + migration_batch_reference="migration_batch:01JHRISMIGRATION01", + actor_reference="keyverse_subject:01JHRISOPERATOR", + approval_reference="approval:01JHUMANCONFIRM", + purpose_code="hris_data_migration", + reason_code="legacy_hris_cutover", + human_confirmed=True, + source_sha256="a" * 64, + source_size_bytes=14_220, + schema_proposal_id="schema_proposal_" + "d" * 32, + table_fingerprint_sha256="b" * 64, + mapping_digest_sha256="c" * 64, + record_count=2, + target_object_codes=("person_record", "employment_record"), + ) + return replace(evidence, **changes) + + +def test_rejects_purpose_text_subclass_that_can_forge_reviewed_constant() -> None: + """Unsafe underlying purpose text must not mint reviewed migration evidence.""" + forged = ForgedEqualityText("shadow_migration", "hris_data_migration") + with pytest.raises(ContractViolation, match="purpose code is malformed"): + build_migration_handoff(_valid_input(purpose_code=forged)) + + +@pytest.mark.parametrize( + ("field_name", "reviewed_value", "message"), + [ + ( + "mhtml_contract_revision", + MHTML_ETL_GATEWAY_REVISION, + "MHTML ETL Gateway contract revision requires revalidation", + ), + ( + "mightyetl_contract_revision", + MIGHTY_ETL_REVISION, + "mightyETL contract revision requires revalidation", + ), + ], +) +def test_rejects_dependency_revision_subclasses_that_forge_pinned_equality( + field_name: str, + reviewed_value: str, + message: str, +) -> None: + """Dependency pins must be exact text, not caller-controlled equality objects.""" + forged = ForgedEqualityText("0" * 40, reviewed_value) + with pytest.raises(ContractViolation, match=message): + build_migration_handoff(_valid_input(**{field_name: forged})) + + +def test_rejects_target_code_subclass_that_forges_allow_list_membership() -> None: + """A value-bearing target cannot impersonate an allowed HRIS object code.""" + forged = ForgedEqualityText("payroll_record", "person_record") + with pytest.raises(ContractViolation, match="migration target object code is malformed"): + build_migration_handoff(_valid_input(target_object_codes=(forged,))) + + +def test_rejects_integer_subclass_that_forges_batch_bounds() -> None: + """Oversized record counts cannot override reviewed numeric comparisons.""" + forged = ForgedCount(MAXIMUM_BATCH_RECORDS + 500) + with pytest.raises(ContractViolation, match="record count must be a positive integer"): + build_migration_handoff(_valid_input(record_count=forged)) + + +def test_rejects_envelope_mode_subclass_that_forges_fixed_privacy_state() -> None: + """Canonical envelope privacy mode must be exact reviewed built-in text.""" + envelope = build_migration_handoff(_valid_input()) + forged = ForgedEqualityText("raw_values", "value_free") + with pytest.raises( + ContractViolation, + match="migration envelope privacy mode must remain value_free", + ): + replace(envelope, privacy_mode=forged) From 54bcef13194e7f9bbe38c9d7a916fd0825f0ae4f Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Fri, 21 Aug 2026 13:06:47 -0700 Subject: [PATCH 2/7] fix(migration): require exact governed runtime primitives --- .../src/orgmetra_migration_adapter/handoff.py | 47 +++++++++++++++---- 1 file changed, 39 insertions(+), 8 deletions(-) diff --git a/packages/migration-adapter/src/orgmetra_migration_adapter/handoff.py b/packages/migration-adapter/src/orgmetra_migration_adapter/handoff.py index 0180c05c9..9c689743c 100644 --- a/packages/migration-adapter/src/orgmetra_migration_adapter/handoff.py +++ b/packages/migration-adapter/src/orgmetra_migration_adapter/handoff.py @@ -101,6 +101,10 @@ class MigrationHandoffEnvelope: def __post_init__(self) -> None: """Reject direct construction that would produce noncanonical evidence.""" + _require_exact_text( + self.contract_version, + "migration envelope contract version is unsupported", + ) if self.contract_version != MIGRATION_CONTRACT_VERSION: raise ContractViolation("migration envelope contract version is unsupported") canonical_targets = _validate_migration_evidence( @@ -123,12 +127,24 @@ def __post_init__(self) -> None: ) if self.target_object_codes != canonical_targets: raise ContractViolation("migration target objects must be sorted and unique") + _require_exact_text( + self.privacy_mode, + "migration envelope privacy mode must remain value_free", + ) if self.privacy_mode != "value_free": raise ContractViolation("migration envelope privacy mode must remain value_free") + _require_exact_text( + self.execution_mode, + "migration envelope execution mode is unsupported", + ) if self.execution_mode != "bounded_atomic_batch": raise ContractViolation("migration envelope execution mode is unsupported") if self.requires_reconciliation is not True: raise ContractViolation("migration completion requires explicit reconciliation") + _require_exact_text( + self.next_action, + "migration envelope next action is noncanonical", + ) if self.next_action != _MIGRATION_NEXT_ACTION: raise ContractViolation("migration envelope next action is noncanonical") @@ -226,15 +242,30 @@ def _validate_migration_evidence( if record_count > MAXIMUM_BATCH_RECORDS: raise ContractViolation("migration batch exceeds the reviewed record bound") canonical_targets = _canonical_target_objects(target_object_codes) + _require_exact_text( + mhtml_contract_revision, + "MHTML ETL Gateway contract revision requires revalidation", + ) if mhtml_contract_revision != MHTML_ETL_GATEWAY_REVISION: raise ContractViolation("MHTML ETL Gateway contract revision requires revalidation") + _require_exact_text( + mightyetl_contract_revision, + "mightyETL contract revision requires revalidation", + ) if mightyetl_contract_revision != MIGHTY_ETL_REVISION: raise ContractViolation("mightyETL contract revision requires revalidation") return canonical_targets +def _require_exact_text(value: object, message: str) -> None: + """Reject caller-controlled string subclasses before equality or serialization.""" + if type(value) is not str: + raise ContractViolation(message) + + def _require_operational_uuid(value: str) -> None: """Require one canonical, non-sentinel tenant UUID before migration handoff.""" + _require_exact_text(value, "tenant record identifier is malformed") try: parsed = UUID(value) except (AttributeError, TypeError, ValueError) as exc: @@ -247,39 +278,39 @@ def _require_operational_uuid(value: str) -> None: def _require_reference(value: str, label: str) -> None: """Require a bounded namespaced opaque reference without echoing bad input.""" - if not isinstance(value, str) or not _REFERENCE_PATTERN.fullmatch(value): + if type(value) is not str or not _REFERENCE_PATTERN.fullmatch(value): raise ContractViolation(f"{label} is malformed") def _require_code(value: str, label: str) -> None: """Require a lowercase snake-case governance code used by stable contracts.""" - if not isinstance(value, str) or not _CODE_PATTERN.fullmatch(value): + if type(value) is not str or not _CODE_PATTERN.fullmatch(value): raise ContractViolation(f"{label} is malformed") def _require_schema_proposal_id(value: str) -> None: """Require the immutable identifier for the reviewed source schema proposal.""" - if not isinstance(value, str) or not _SCHEMA_PROPOSAL_PATTERN.fullmatch(value): + if type(value) is not str or not _SCHEMA_PROPOSAL_PATTERN.fullmatch(value): raise ContractViolation("schema proposal identifier is malformed") def _require_sha256(value: str, label: str) -> None: """Require a lowercase SHA-256 hex digest for provenance-bearing evidence.""" - if not isinstance(value, str) or not _SHA256_PATTERN.fullmatch(value): + if type(value) is not str or not _SHA256_PATTERN.fullmatch(value): raise ContractViolation(f"{label} must be lowercase SHA-256") def _require_positive_int(value: int, label: str) -> None: - """Require a positive integer while rejecting booleans masquerading as counts.""" - if isinstance(value, bool) or not isinstance(value, int) or value <= 0: + """Require an exact positive integer so callers cannot override comparisons.""" + if type(value) is not int or value <= 0: raise ContractViolation(f"{label} must be a positive integer") def _canonical_target_objects(values: tuple[str, ...]) -> tuple[str, ...]: """Validate supported HRIS targets and return their stable canonical ordering.""" - if not isinstance(values, tuple) or not values: + if type(values) is not tuple or not values: raise ContractViolation("migration target objects must be a non-empty tuple") - if any(not isinstance(value, str) for value in values): + if any(type(value) is not str for value in values): raise ContractViolation("migration target object code is malformed") if len(set(values)) != len(values): raise ContractViolation("migration target objects must be unique") From aa30d23d4f5a5f57c37a719c24f9d4b015f07cd2 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Fri, 21 Aug 2026 13:08:36 -0700 Subject: [PATCH 3/7] docs(migration): trace exact runtime evidence integrity --- docs/traceability/migration-handoff.md | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/docs/traceability/migration-handoff.md b/docs/traceability/migration-handoff.md index 27ec3f113..849d80bab 100644 --- a/docs/traceability/migration-handoff.md +++ b/docs/traceability/migration-handoff.md @@ -2,20 +2,21 @@ ## Status -Active-PR only. This evidence does not describe protected-`develop` product truth until the owning PR integrates. +Protected `develop` currently contains the governed migration-handoff boundary. PR #71 hardens only Orgmetra-owned runtime evidence integrity on top of that protected truth; it does not mutate MHTML ETL Gateway, mightyETL, or any other dedicated-writer dependency. | Requirement | Decision / owner contract | Production implementation | Executable evidence | |---|---|---|---| | Bind the immutable source without copying source values | MHTML ETL Gateway revision `779254927abb1e7cee80fd949907ccd03f9fc7be`; ADR 0012 | `MigrationHandoffInput.source_sha256`, `source_size_bytes`, value-free proposal identity/fingerprint | deterministic handoff and malformed-digest regressions | -| Preserve accountable migration governance | ADR 0012 | tenant UUID, migration-batch reference, actor, approval, `hris_data_migration` purpose, reason, strict human confirmation | malformed context and non-boolean confirmation matrix | -| Revalidate foreign contract drift rather than silently adapting | ADR 0012; exact owner revisions | `MHTML_ETL_GATEWAY_REVISION`, `MIGHTY_ETL_REVISION` | stale-revision regressions | -| Keep the handoff bounded | mightyETL reviewed bounded-atomic-batch contract; ADR 0012 | `MAXIMUM_BATCH_RECORDS = 1000`; positive non-boolean record count | zero/bool/over-bound regressions | -| Restrict import targets to authoritative HRIS core | Orgmetra core model; ADR 0001; ADR 0012 | allowlist for `person_record`, `employment_record`, `organization_unit`, `job_profile`, `position_record`, `assignment_record` | all-core-family success plus unsupported/duplicate target rejection | +| Preserve accountable migration governance | ADR 0012 | tenant UUID, migration-batch reference, actor, approval, `hris_data_migration` purpose, reason, strict human confirmation | malformed context, non-boolean confirmation, and hostile runtime-subclass regressions | +| Prevent runtime objects from forging reviewed evidence | Python data-model semantics; PR #71 | exact built-in `str`, `int`, and `tuple` primitives at trust-bearing validation/equality/hash/comparison boundaries | `test_runtime_evidence_integrity.py` purpose, dependency-revision, target allow-list, batch-bound, and envelope-mode adversarial regressions | +| Revalidate foreign contract drift rather than silently adapting | ADR 0012; exact owner revisions | `MHTML_ETL_GATEWAY_REVISION`, `MIGHTY_ETL_REVISION`, each requiring exact built-in text before equality | stale-revision plus hostile revision-subclass regressions | +| Keep the handoff bounded | mightyETL reviewed bounded-atomic-batch contract; ADR 0012 | `MAXIMUM_BATCH_RECORDS = 1000`; exact built-in positive integer record count | zero/bool/over-bound plus hostile integer-subclass regression | +| Restrict import targets to authoritative HRIS core | Orgmetra core model; ADR 0001; ADR 0012 | exact built-in tuple and string elements followed by allow-list validation for `person_record`, `employment_record`, `organization_unit`, `job_profile`, `position_record`, `assignment_record` | all-core-family success plus unsupported/duplicate/hostile-subclass target rejection | | Prevent raw-value/credential shadow stores | MHTML value-free contract; ADR 0012 | package input/output has no raw header, source value, credential, connection or SQL field | serialized-envelope non-disclosure regression and public API review | | Make pre-write evidence reproducible | W3C PROV-DM design traceability; ADR 0012 | sorted target codes, canonical JSON, SHA-256 digest | reversed-order equivalence plus exact `hashlib.sha256(canonical_json)` assertion | -| Keep requested execution semantics separate from observed outcomes | mightyETL owner contract; ADR 0012 | `execution_mode="bounded_atomic_batch"` records only the requested/contracted subsequent execution mode; it is not proof of writes, completion, or observed atomicity | direct-constructor canonical-mode rejection plus documentation contract | -| Do not confuse handoff with migration completion | ADR 0012 | `requires_reconciliation=True` plus actionable `next_action` | direct-constructor bypass rejection and deterministic handoff regression | +| Keep requested execution semantics separate from observed outcomes | mightyETL owner contract; ADR 0012 | exact built-in `execution_mode="bounded_atomic_batch"` records only the requested/contracted subsequent execution mode; it is not proof of writes, completion, or observed atomicity | direct-constructor canonical-mode and hostile-subclass rejection plus documentation contract | +| Do not confuse handoff with migration completion | ADR 0012 | `requires_reconciliation=True` plus exact built-in actionable `next_action` | direct-constructor bypass rejection and deterministic handoff regression | | Preserve dedicated-writer ownership | ADR 0002; ADR 0012 | no MHTML/mightyETL source mutation, no network call, no cross-service SQL | package dependency surface and code review | | Keep owned behavior fully covered | Orgmetra quality policy | exact-head migration quality workflow | 100% statement and branch coverage gate | -A consumer MUST obtain separate execution-outcome evidence from the configured owner boundary and reconcile it before asserting migration completion or atomic execution. The pre-write envelope alone is never completion evidence. +A consumer MUST obtain separate execution-outcome evidence from the configured owner boundary and reconcile it before asserting migration completion or atomic execution. The pre-write envelope alone is never completion evidence. PR #71 changes only the local validation trust boundary: Python user-defined subclasses can override rich comparison and hashing behavior, so trust-bearing primitives are normalized by rejection to exact built-in runtime types before reviewed equality, membership, bounds, or canonical serialization are evaluated. From 9688b6a753ecc1915184442a1d65041f5e89a339 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Fri, 21 Aug 2026 13:08:52 -0700 Subject: [PATCH 4/7] docs(migration): record runtime integrity language evidence --- docs/doctoring/migration-handoff-references.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/docs/doctoring/migration-handoff-references.md b/docs/doctoring/migration-handoff-references.md index 24959d74d..c514394d5 100644 --- a/docs/doctoring/migration-handoff-references.md +++ b/docs/doctoring/migration-handoff-references.md @@ -2,7 +2,7 @@ ## Status -Active-PR evidence only. Protected `develop` does not ship this migration handoff until the owning PR integrates. +Protected `develop` ships the governed migration-handoff boundary. PR #71 records an Orgmetra-local runtime-integrity hardening of that boundary. The foreign dependency contracts remain read-only and unchanged. ## Exact dependency contracts @@ -10,10 +10,11 @@ Active-PR evidence only. Protected `develop` does not ship this migration handof - ContextualWisdomLab. (2026). *MHTML ETL Gateway value-free schema proposal contract* [Source code]. `ContextualWisdomLab/mhtml-etl-gateway`, revision `779254927abb1e7cee80fd949907ccd03f9fc7be`. GitHub. https://github.com/ContextualWisdomLab/mhtml-etl-gateway/commit/779254927abb1e7cee80fd949907ccd03f9fc7be. The reviewed proposal contract exposes `schema_proposal_id`, `source_hash_sha256`, and `table_fingerprint_sha256` while excluding raw headers and values. - ContextualWisdomLab. (2026). *mightyETL bounded atomic batch contract* [Source code]. `ContextualWisdomLab/mightyETL`, revision `ba8911f50ed20a39927a0d51c0cf20f9b7c91820`. GitHub. https://github.com/ContextualWisdomLab/mightyETL/commit/ba8911f50ed20a39927a0d51c0cf20f9b7c91820. The reviewed contract prevalidates one bounded request before database writes and executes accepted writes inside one transaction; Orgmetra does not copy or extend its runtime semantics in this slice. -## Authoritative standards +## Authoritative standards and language semantics +- Python Software Foundation. (2026). *Data model — Python 3.14 documentation*. Python documentation. https://docs.python.org/3.14/reference/datamodel.html. Python's data model defines rich comparison special methods such as `__eq__`, `__ne__`, `__le__`, and `__gt__`, and defines `__hash__` as the hook used by hashed collections including sets and dictionaries. Because user-defined subclasses can provide these methods, caller-controlled subclasses must not be allowed to determine reviewed equality, membership, or bounds at an immutable governance-evidence boundary. - World Wide Web Consortium. (2013, April 30). *PROV-DM: The PROV data model* (W3C Recommendation). https://www.w3.org/TR/2013/REC-prov-dm-20130430/ - National Institute of Standards and Technology. (2020). *Security and privacy controls for information systems and organizations* (NIST Special Publication 800-53, Revision 5). https://doi.org/10.6028/NIST.SP.800-53r5 - National Institute of Standards and Technology. (2025, August 27). *NIST releases revision to SP 800-53 security and privacy controls* (Release 5.2.0 notice). https://csrc.nist.gov/news/2025/nist-releases-revision-to-sp-800-53-controls -NIST's official CSRC publication page and release notice identify Release 5.2.0 as the finalized August 27, 2025 update. Orgmetra uses the public information-integrity and provenance principles as design traceability only and does not claim NIST, ISO, SOC 2, or other certification from this package. +NIST's official CSRC publication page and release notice identify Release 5.2.0 as the finalized August 27, 2025 update. Orgmetra uses the public information-integrity and provenance principles as design traceability only and does not claim NIST, ISO, SOC 2, or other certification from this package. The Python language reference is used narrowly to justify exact built-in primitive requirements at the Orgmetra trust boundary; it does not change either foreign owner's published contract. From 299d671f74fc4c8a6043588cebb5b4065f0d16a6 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Fri, 21 Aug 2026 13:09:22 -0700 Subject: [PATCH 5/7] docs(migration): explain fail-closed runtime primitives --- packages/migration-adapter/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/migration-adapter/README.md b/packages/migration-adapter/README.md index f0eb5c23a..a839fd2df 100644 --- a/packages/migration-adapter/README.md +++ b/packages/migration-adapter/README.md @@ -4,6 +4,8 @@ This package creates **value-free, fail-closed migration handoff evidence** befo Use it when an operator has already inspected a source through the published MHTML ETL Gateway contract and has an approved mapping for one bounded Orgmetra HRIS batch. The package binds that evidence to an Orgmetra tenant, accountable actor, approval, purpose, mapping digest, source digest, target HRIS object families, and exact reviewed dependency revisions. +Trust-bearing primitive fields are fail-closed runtime evidence. The adapter accepts exact built-in strings for identifiers, references, codes, digests, dependency revisions, and fixed envelope states; exact built-in integers for bounded counts and sizes; and an exact tuple of exact string target codes. Caller-defined subclasses are rejected before reviewed equality, hashed allow-list membership, numeric bounds, or canonical JSON serialization can run, so custom Python comparison/hash methods cannot make accepted governance differ from the immutable evidence that is recorded. + It deliberately does **not**: - parse MHTML or copy the MHTML ETL Gateway implementation; From 1d7ed5bbfb18b35d589c69a6e8d93754ba299589 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Tue, 25 Aug 2026 20:37:14 +0900 Subject: [PATCH 6/7] fix(migration): narrow tenant UUID parse failure to ValueError _require_exact_text guarantees exact str before UUID(value), so only ValueError can escape; AttributeError/TypeError arms were unreachable after the runtime-integrity guard landed. Addresses Devin review observation on PR #71. --- .../migration-adapter/src/orgmetra_migration_adapter/handoff.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/migration-adapter/src/orgmetra_migration_adapter/handoff.py b/packages/migration-adapter/src/orgmetra_migration_adapter/handoff.py index 9c689743c..750391cb1 100644 --- a/packages/migration-adapter/src/orgmetra_migration_adapter/handoff.py +++ b/packages/migration-adapter/src/orgmetra_migration_adapter/handoff.py @@ -268,7 +268,7 @@ def _require_operational_uuid(value: str) -> None: _require_exact_text(value, "tenant record identifier is malformed") try: parsed = UUID(value) - except (AttributeError, TypeError, ValueError) as exc: + except ValueError as exc: raise ContractViolation("tenant record identifier is malformed") from exc if str(parsed) != value: raise ContractViolation("tenant record identifier must use canonical UUID text") From 883c4bc9dc62b712de5f2a355251d405d2810957 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Sun, 6 Sep 2026 16:04:56 +0900 Subject: [PATCH 7/7] docs(migration): separate released and proposal dependency evidence --- docs/doctoring/migration-handoff-references.md | 10 +++++----- docs/traceability/migration-handoff.md | 14 ++++++++------ .../src/orgmetra_migration_adapter/handoff.py | 7 ++++++- 3 files changed, 19 insertions(+), 12 deletions(-) diff --git a/docs/doctoring/migration-handoff-references.md b/docs/doctoring/migration-handoff-references.md index c514394d5..eb731e3f2 100644 --- a/docs/doctoring/migration-handoff-references.md +++ b/docs/doctoring/migration-handoff-references.md @@ -2,13 +2,13 @@ ## Status -Protected `develop` ships the governed migration-handoff boundary. PR #71 records an Orgmetra-local runtime-integrity hardening of that boundary. The foreign dependency contracts remain read-only and unchanged. +Protected `develop` ships the governed migration-handoff boundary. PR #71 records an Orgmetra-local runtime-integrity hardening of that boundary. Foreign owner code remains read-only: MHTML ETL Gateway is bound to an immutable published release, while the reviewed mightyETL snapshot is not yet a released production dependency and remains an explicit acceptance prerequisite in Orgmetra #256. ## Exact dependency contracts -- ContextualWisdomLab. (2026). *MHTML ETL Gateway API contract* [Source code]. `ContextualWisdomLab/mhtml-etl-gateway`, revision `779254927abb1e7cee80fd949907ccd03f9fc7be`. GitHub. https://github.com/ContextualWisdomLab/mhtml-etl-gateway/commit/779254927abb1e7cee80fd949907ccd03f9fc7be. The reviewed `0.4.0` API exposes source SHA-256 identity and value-free schema/handoff contracts without database writes, network transport, authentication, or raw source values. -- ContextualWisdomLab. (2026). *MHTML ETL Gateway value-free schema proposal contract* [Source code]. `ContextualWisdomLab/mhtml-etl-gateway`, revision `779254927abb1e7cee80fd949907ccd03f9fc7be`. GitHub. https://github.com/ContextualWisdomLab/mhtml-etl-gateway/commit/779254927abb1e7cee80fd949907ccd03f9fc7be. The reviewed proposal contract exposes `schema_proposal_id`, `source_hash_sha256`, and `table_fingerprint_sha256` while excluding raw headers and values. -- ContextualWisdomLab. (2026). *mightyETL bounded atomic batch contract* [Source code]. `ContextualWisdomLab/mightyETL`, revision `ba8911f50ed20a39927a0d51c0cf20f9b7c91820`. GitHub. https://github.com/ContextualWisdomLab/mightyETL/commit/ba8911f50ed20a39927a0d51c0cf20f9b7c91820. The reviewed contract prevalidates one bounded request before database writes and executes accepted writes inside one transaction; Orgmetra does not copy or extend its runtime semantics in this slice. +- ContextualWisdomLab. (2026). *MHTML ETL Gateway v0.4.0* [Software release]. `ContextualWisdomLab/mhtml-etl-gateway`, immutable release `v0.4.0`, target revision `779254927abb1e7cee80fd949907ccd03f9fc7be`. GitHub. https://github.com/ContextualWisdomLab/mhtml-etl-gateway/releases/tag/v0.4.0. The released API exposes source SHA-256 identity and value-free schema/handoff contracts without database writes, network transport, authentication, or raw source values. +- ContextualWisdomLab. (2026). *MHTML ETL Gateway value-free schema proposal contract* [Source code in immutable release]. `ContextualWisdomLab/mhtml-etl-gateway`, release `v0.4.0`, target revision `779254927abb1e7cee80fd949907ccd03f9fc7be`. GitHub. https://github.com/ContextualWisdomLab/mhtml-etl-gateway/commit/779254927abb1e7cee80fd949907ccd03f9fc7be. The released proposal contract exposes `schema_proposal_id`, `source_hash_sha256`, and `table_fingerprint_sha256` while excluding raw headers and values. +- ContextualWisdomLab. (2026). *mightyETL bounded atomic batch contract* [Unreleased source snapshot]. `ContextualWisdomLab/mightyETL`, reviewed revision `ba8911f50ed20a39927a0d51c0cf20f9b7c91820`. GitHub. https://github.com/ContextualWisdomLab/mightyETL/commit/ba8911f50ed20a39927a0d51c0cf20f9b7c91820. The reviewed snapshot prevalidates one bounded request before database writes and executes accepted writes inside one transaction. It is design/proposal evidence only until the canonical owner publishes an immutable release binding that contract; Orgmetra #256 tracks that prerequisite. ## Authoritative standards and language semantics @@ -17,4 +17,4 @@ Protected `develop` ships the governed migration-handoff boundary. PR #71 record - National Institute of Standards and Technology. (2020). *Security and privacy controls for information systems and organizations* (NIST Special Publication 800-53, Revision 5). https://doi.org/10.6028/NIST.SP.800-53r5 - National Institute of Standards and Technology. (2025, August 27). *NIST releases revision to SP 800-53 security and privacy controls* (Release 5.2.0 notice). https://csrc.nist.gov/news/2025/nist-releases-revision-to-sp-800-53-controls -NIST's official CSRC publication page and release notice identify Release 5.2.0 as the finalized August 27, 2025 update. Orgmetra uses the public information-integrity and provenance principles as design traceability only and does not claim NIST, ISO, SOC 2, or other certification from this package. The Python language reference is used narrowly to justify exact built-in primitive requirements at the Orgmetra trust boundary; it does not change either foreign owner's published contract. +NIST's official CSRC publication page and release notice identify Release 5.2.0 as the finalized August 27, 2025 update. Orgmetra uses the public information-integrity and provenance principles as design traceability only and does not claim NIST, ISO, SOC 2, or other certification from this package. The Python language reference is used narrowly to justify exact built-in primitive requirements at the Orgmetra trust boundary. None of these references elevates the unreleased mightyETL source snapshot into a published dependency contract. diff --git a/docs/traceability/migration-handoff.md b/docs/traceability/migration-handoff.md index 849d80bab..37a5d574e 100644 --- a/docs/traceability/migration-handoff.md +++ b/docs/traceability/migration-handoff.md @@ -2,21 +2,23 @@ ## Status -Protected `develop` currently contains the governed migration-handoff boundary. PR #71 hardens only Orgmetra-owned runtime evidence integrity on top of that protected truth; it does not mutate MHTML ETL Gateway, mightyETL, or any other dedicated-writer dependency. +Protected-parent adoption snapshot `develop@eb9757f8649aaad026a9865508d9aad50c1a7a4f` contains the governed migration-handoff boundary and protected #161 repository-quality consolidation. PR #71 hardens only Orgmetra-owned runtime evidence integrity on top of that snapshot; it does not mutate MHTML ETL Gateway, mightyETL, or any other dedicated-writer dependency. The protected branch must be re-read before merge rather than treating this snapshot as perpetual current truth. | Requirement | Decision / owner contract | Production implementation | Executable evidence | |---|---|---|---| -| Bind the immutable source without copying source values | MHTML ETL Gateway revision `779254927abb1e7cee80fd949907ccd03f9fc7be`; ADR 0012 | `MigrationHandoffInput.source_sha256`, `source_size_bytes`, value-free proposal identity/fingerprint | deterministic handoff and malformed-digest regressions | +| Bind the immutable source without copying source values | MHTML ETL Gateway immutable release `v0.4.0`, target revision `779254927abb1e7cee80fd949907ccd03f9fc7be`; ADR 0012 | `MigrationHandoffInput.source_sha256`, `source_size_bytes`, value-free proposal identity/fingerprint | deterministic handoff and malformed-digest regressions | | Preserve accountable migration governance | ADR 0012 | tenant UUID, migration-batch reference, actor, approval, `hris_data_migration` purpose, reason, strict human confirmation | malformed context, non-boolean confirmation, and hostile runtime-subclass regressions | | Prevent runtime objects from forging reviewed evidence | Python data-model semantics; PR #71 | exact built-in `str`, `int`, and `tuple` primitives at trust-bearing validation/equality/hash/comparison boundaries | `test_runtime_evidence_integrity.py` purpose, dependency-revision, target allow-list, batch-bound, and envelope-mode adversarial regressions | -| Revalidate foreign contract drift rather than silently adapting | ADR 0012; exact owner revisions | `MHTML_ETL_GATEWAY_REVISION`, `MIGHTY_ETL_REVISION`, each requiring exact built-in text before equality | stale-revision plus hostile revision-subclass regressions | -| Keep the handoff bounded | mightyETL reviewed bounded-atomic-batch contract; ADR 0012 | `MAXIMUM_BATCH_RECORDS = 1000`; exact built-in positive integer record count | zero/bool/over-bound plus hostile integer-subclass regression | +| Revalidate foreign contract drift rather than silently adapting | ADR 0012; released MHTML identity plus reviewed mightyETL snapshot | `MHTML_ETL_GATEWAY_REVISION`; proposal-only `MIGHTY_ETL_REVISION`, each requiring exact built-in text before equality | stale-revision plus hostile revision-subclass regressions; release binding tracked by #256 | +| Keep the handoff bounded | mightyETL bounded-atomic-batch design snapshot; ADR 0012 | `MAXIMUM_BATCH_RECORDS = 1000`; exact built-in positive integer record count | zero/bool/over-bound plus hostile integer-subclass regression; production dependency acceptance blocked by #256 | | Restrict import targets to authoritative HRIS core | Orgmetra core model; ADR 0001; ADR 0012 | exact built-in tuple and string elements followed by allow-list validation for `person_record`, `employment_record`, `organization_unit`, `job_profile`, `position_record`, `assignment_record` | all-core-family success plus unsupported/duplicate/hostile-subclass target rejection | | Prevent raw-value/credential shadow stores | MHTML value-free contract; ADR 0012 | package input/output has no raw header, source value, credential, connection or SQL field | serialized-envelope non-disclosure regression and public API review | | Make pre-write evidence reproducible | W3C PROV-DM design traceability; ADR 0012 | sorted target codes, canonical JSON, SHA-256 digest | reversed-order equivalence plus exact `hashlib.sha256(canonical_json)` assertion | -| Keep requested execution semantics separate from observed outcomes | mightyETL owner contract; ADR 0012 | exact built-in `execution_mode="bounded_atomic_batch"` records only the requested/contracted subsequent execution mode; it is not proof of writes, completion, or observed atomicity | direct-constructor canonical-mode and hostile-subclass rejection plus documentation contract | +| Keep requested execution semantics separate from observed outcomes | reviewed mightyETL design snapshot; ADR 0012 | exact built-in `execution_mode="bounded_atomic_batch"` records only the requested subsequent execution mode; it is not proof of writes, completion, or observed atomicity | direct-constructor canonical-mode and hostile-subclass rejection plus documentation contract | | Do not confuse handoff with migration completion | ADR 0012 | `requires_reconciliation=True` plus exact built-in actionable `next_action` | direct-constructor bypass rejection and deterministic handoff regression | | Preserve dedicated-writer ownership | ADR 0002; ADR 0012 | no MHTML/mightyETL source mutation, no network call, no cross-service SQL | package dependency surface and code review | -| Keep owned behavior fully covered | Orgmetra quality policy | exact-head migration quality workflow | 100% statement and branch coverage gate | +| Keep owned behavior fully covered | Orgmetra quality policy | canonical Foundation CI runs the migration-adapter package contract | 100% statement and branch coverage gate | A consumer MUST obtain separate execution-outcome evidence from the configured owner boundary and reconcile it before asserting migration completion or atomic execution. The pre-write envelope alone is never completion evidence. PR #71 changes only the local validation trust boundary: Python user-defined subclasses can override rich comparison and hashing behavior, so trust-bearing primitives are normalized by rejection to exact built-in runtime types before reviewed equality, membership, bounds, or canonical serialization are evaluated. + +The MHTML dependency is release-bound through immutable `v0.4.0`. The mightyETL revision remains reviewed design evidence only because the canonical owner has no published release at this point. Issue #256 is therefore a merge/release prerequisite: Orgmetra must bind the consumer contract to an immutable mightyETL owner release before claiming that execution boundary as a released production dependency. diff --git a/packages/migration-adapter/src/orgmetra_migration_adapter/handoff.py b/packages/migration-adapter/src/orgmetra_migration_adapter/handoff.py index 750391cb1..b2dc0f1a8 100644 --- a/packages/migration-adapter/src/orgmetra_migration_adapter/handoff.py +++ b/packages/migration-adapter/src/orgmetra_migration_adapter/handoff.py @@ -2,7 +2,10 @@ This module owns only Orgmetra's pre-write governance envelope. It does not parse MHTML, transform source values, call mightyETL, hold credentials, or write HRIS -tables. Those responsibilities remain behind their published owner contracts. +tables. Those responsibilities remain behind their owner boundaries. The MHTML +revision is bound to an immutable owner release; the mightyETL revision remains +reviewed proposal evidence until its canonical owner publishes an immutable +release binding that execution contract. """ from __future__ import annotations @@ -16,6 +19,8 @@ MHTML_ETL_GATEWAY_REVISION: Final = "779254927abb1e7cee80fd949907ccd03f9fc7be" +# Reviewed owner snapshot only. Orgmetra #256 blocks release acceptance until +# mightyETL publishes an immutable release binding this execution contract. MIGHTY_ETL_REVISION: Final = "ba8911f50ed20a39927a0d51c0cf20f9b7c91820" MIGRATION_CONTRACT_VERSION: Final = "orgmetra.migration_handoff.v1" MAXIMUM_BATCH_RECORDS: Final = 1000