From 4816ffc7a8fc084f646ae5ef32ad374e58ad342a Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Wed, 29 Jul 2026 03:01:20 +0000 Subject: [PATCH 01/23] WIP: business --- dag/gunbc/scm_compatibility_shape.dag | 316 ++++++++++++++++++++++++++ 1 file changed, 316 insertions(+) create mode 100644 dag/gunbc/scm_compatibility_shape.dag diff --git a/dag/gunbc/scm_compatibility_shape.dag b/dag/gunbc/scm_compatibility_shape.dag new file mode 100644 index 00000000000..5dbc033265f --- /dev/null +++ b/dag/gunbc/scm_compatibility_shape.dag @@ -0,0 +1,316 @@ +module gunbc.scm_compatibility_shape + +import std.types { Bool, List, NonEmptyStr } + +data scm_compatibility_shape_note: NonEmptyStr = "R1 compatibility-realization shape extracted from the independently executing Git, Mercurial, and Pijul R0 boundaries. The shared carrier owns only roles demonstrated by all three: an opaque realization and target handle, a handle to native generation evidence, honest capture fidelity, realization-specific preservation/loss facts, projection plus independent read-back, idempotent repair identity, and an explicit conditional-advance capability. Native evidence remains in adapter-specific typed receipts; this presentation projection is not a semantic, policy, commit, or Applied receipt. Dispatch is a generic handler value, never ScmKind or a vendor switch. A fourth realization supplies one handler and does not edit this module or the native interaction contract." + +type CompatibilityRealizationHandle = NonEmptyStr where brand("CompatibilityRealizationHandle") +type CompatibilityTargetHandle = NonEmptyStr where brand("CompatibilityTargetHandle") +type CompatibilityGenerationEvidenceHandle = NonEmptyStr where brand("CompatibilityGenerationEvidenceHandle") +type CompatibilityProjectionHandle = NonEmptyStr where brand("CompatibilityProjectionHandle") +type CompatibilityReadBackHandle = NonEmptyStr where brand("CompatibilityReadBackHandle") +type CompatibilityRepairHandle = NonEmptyStr where brand("CompatibilityRepairHandle") + +type CompatibilityCaptureClass + = CompatibilityEndpointStateCaptured + | CompatibilityUpstreamChangeEvidenceCaptured + | CompatibilityNativeProposalCaptured + +type CompatibilityCaptureClassFold { + endpoint_state: fn() -> R + upstream_change_evidence: fn() -> R + native_proposal: fn() -> R +} + +fn compatibility_capture_class_fold( + capture: CompatibilityCaptureClass, + fold: CompatibilityCaptureClassFold, +) -> R { + match capture { + CompatibilityEndpointStateCaptured => fold.endpoint_state() + CompatibilityUpstreamChangeEvidenceCaptured => fold.upstream_change_evidence() + CompatibilityNativeProposalCaptured => fold.native_proposal() + } +} + +type CompatibilityFidelityAxis + = CompatibilityEndpointState + | CompatibilityUpstreamChangeEvidence + | CompatibilityNativeProposalContract + | CompatibilityHistory + | CompatibilityPublication + | CompatibilityConflictFacts + | CompatibilityPathAndMode + | CompatibilityAvailability + | CompatibilityNativeIdentity + +type CompatibilityFidelityDisposition + = CompatibilityFidelityPreserved + | CompatibilityFidelityDowngraded { cause: NonEmptyStr } + | CompatibilityFidelityUnavailable { cause: NonEmptyStr } + +type CompatibilityFidelityDispositionFold { + preserved: fn() -> R + downgraded: fn(NonEmptyStr) -> R + unavailable: fn(NonEmptyStr) -> R +} + +fn compatibility_fidelity_disposition_fold( + disposition: CompatibilityFidelityDisposition, + fold: CompatibilityFidelityDispositionFold, +) -> R { + match disposition { + CompatibilityFidelityPreserved => fold.preserved() + CompatibilityFidelityDowngraded { cause } => fold.downgraded(cause) + CompatibilityFidelityUnavailable { cause } => fold.unavailable(cause) + } +} + +type CompatibilityFidelityFact { + axis: CompatibilityFidelityAxis + disposition: CompatibilityFidelityDisposition +} + +type CompatibilityFidelityProfile { + first: CompatibilityFidelityFact + remaining: List +} + +fn compatibility_fidelity_profile( + first: CompatibilityFidelityFact, + remaining: List, +) -> CompatibilityFidelityProfile { + CompatibilityFidelityProfile { + first: first, + remaining: remaining, + } +} + +type CompatibilityAdvanceGuarantee + = CompatibilityExactCompareAndAdvance + | CompatibilitySerializedConditionalAdvance + | CompatibilityUpstreamSpecificConditionalAdvance + +type CompatibilityAdvanceCapability + = CompatibilityAdvanceModeled { + guarantee: CompatibilityAdvanceGuarantee, + } + | CompatibilityAdvanceExecutedAndReadBack { + guarantee: CompatibilityAdvanceGuarantee, + } + | CompatibilityAdvanceUnavailable { cause: NonEmptyStr } + +type CompatibilityAdvanceCapabilityFold { + modeled: fn(CompatibilityAdvanceGuarantee) -> R + executed_and_read_back: fn(CompatibilityAdvanceGuarantee) -> R + unavailable: fn(NonEmptyStr) -> R +} + +fn compatibility_advance_capability_fold( + capability: CompatibilityAdvanceCapability, + fold: CompatibilityAdvanceCapabilityFold, +) -> R { + match capability { + CompatibilityAdvanceModeled { guarantee } => fold.modeled(guarantee) + CompatibilityAdvanceExecutedAndReadBack { guarantee } => + fold.executed_and_read_back(guarantee) + CompatibilityAdvanceUnavailable { cause } => fold.unavailable(cause) + } +} + +type CompatibilityAdvanceRequirement + = CompatibilityObservationOnly + | CompatibilityModeledAdvanceRequired { + guarantee: CompatibilityAdvanceGuarantee, + } + | CompatibilityExecutedAdvanceRequired { + guarantee: CompatibilityAdvanceGuarantee, + } + +type CompatibilityAdvanceRequirementFold { + observation_only: fn() -> R + modeled_required: fn(CompatibilityAdvanceGuarantee) -> R + executed_required: fn(CompatibilityAdvanceGuarantee) -> R +} + +fn compatibility_advance_requirement_fold( + requirement: CompatibilityAdvanceRequirement, + fold: CompatibilityAdvanceRequirementFold, +) -> R { + match requirement { + CompatibilityObservationOnly => fold.observation_only() + CompatibilityModeledAdvanceRequired { guarantee } => + fold.modeled_required(guarantee) + CompatibilityExecutedAdvanceRequired { guarantee } => + fold.executed_required(guarantee) + } +} + +type CompatibilityCapabilityCheck + = CompatibilityCapabilitySatisfied + | CompatibilityCapabilityRefused { + requirement: CompatibilityAdvanceRequirement, + observed: CompatibilityAdvanceCapability, + } + +type CompatibilityCapabilityCheckFold { + satisfied: fn() -> R + refused: fn(CompatibilityAdvanceRequirement, CompatibilityAdvanceCapability) -> R +} + +fn compatibility_capability_check_fold( + check: CompatibilityCapabilityCheck, + fold: CompatibilityCapabilityCheckFold, +) -> R { + match check { + CompatibilityCapabilitySatisfied => fold.satisfied() + CompatibilityCapabilityRefused { requirement, observed } => + fold.refused(requirement, observed) + } +} + +fn compatibility_modeled_requirement_check( + required: CompatibilityAdvanceGuarantee, + observed: CompatibilityAdvanceCapability, + original: CompatibilityAdvanceRequirement, +) -> CompatibilityCapabilityCheck { + compatibility_advance_capability_fold( + capability: observed, + fold: CompatibilityAdvanceCapabilityFold { + modeled: fn(actual) { + if actual == required { + CompatibilityCapabilitySatisfied + } else { + CompatibilityCapabilityRefused { + requirement: original, + observed: observed, + } + } + }, + executed_and_read_back: fn(actual) { + if actual == required { + CompatibilityCapabilitySatisfied + } else { + CompatibilityCapabilityRefused { + requirement: original, + observed: observed, + } + } + }, + unavailable: fn(_) { + CompatibilityCapabilityRefused { + requirement: original, + observed: observed, + } + }, + }, + ) +} + +fn compatibility_executed_requirement_check( + required: CompatibilityAdvanceGuarantee, + observed: CompatibilityAdvanceCapability, + original: CompatibilityAdvanceRequirement, +) -> CompatibilityCapabilityCheck { + compatibility_advance_capability_fold( + capability: observed, + fold: CompatibilityAdvanceCapabilityFold { + modeled: fn(_) { + CompatibilityCapabilityRefused { + requirement: original, + observed: observed, + } + }, + executed_and_read_back: fn(actual) { + if actual == required { + CompatibilityCapabilitySatisfied + } else { + CompatibilityCapabilityRefused { + requirement: original, + observed: observed, + } + } + }, + unavailable: fn(_) { + CompatibilityCapabilityRefused { + requirement: original, + observed: observed, + } + }, + }, + ) +} + +fn compatibility_check_advance_requirement( + requirement: CompatibilityAdvanceRequirement, + observed: CompatibilityAdvanceCapability, +) -> CompatibilityCapabilityCheck { + compatibility_advance_requirement_fold( + requirement: requirement, + fold: CompatibilityAdvanceRequirementFold { + observation_only: fn() { + CompatibilityCapabilitySatisfied + }, + modeled_required: fn(required) { + compatibility_modeled_requirement_check( + required: required, + observed: observed, + original: requirement, + ) + }, + executed_required: fn(required) { + compatibility_executed_requirement_check( + required: required, + observed: observed, + original: requirement, + ) + }, + }, + ) +} + +type CompatibilityProjectionReceipt { + realization: CompatibilityRealizationHandle + target: CompatibilityTargetHandle + generation_evidence: CompatibilityGenerationEvidenceHandle + capture: CompatibilityCaptureClass + projection: CompatibilityProjectionHandle + read_back: CompatibilityReadBackHandle + repair: CompatibilityRepairHandle + advance: CompatibilityAdvanceCapability + fidelity: CompatibilityFidelityProfile +} + +type CompatibilityProjectionHandler { + project: fn(NativeReceipt) -> CompatibilityProjectionReceipt +} + +fn compatibility_projection_from_handler( + handler: CompatibilityProjectionHandler, + receipt: NativeReceipt, +) -> CompatibilityProjectionReceipt { + handler.project(receipt) +} + +fn compatibility_projection_same_binding( + left: CompatibilityProjectionReceipt, + right: CompatibilityProjectionReceipt, +) -> Bool { + left.realization == right.realization + && left.target == right.target +} + +fn compatibility_projection_upsert( + existing: List, + projection: CompatibilityProjectionReceipt, +) -> List { + append( + existing |> filter(row => + !compatibility_projection_same_binding( + left: row, + right: projection, + ) + ), + items: [projection], + ) +} From 014f821c70f9bd3e7bcde1e15f5a2d6f0e47acf2 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Wed, 29 Jul 2026 03:11:53 +0000 Subject: [PATCH 02/23] WIP: business --- dag/gunbc/scm_compatibility/git.dag | 220 ++++++++++++++++++++++++++++ 1 file changed, 220 insertions(+) create mode 100644 dag/gunbc/scm_compatibility/git.dag diff --git a/dag/gunbc/scm_compatibility/git.dag b/dag/gunbc/scm_compatibility/git.dag new file mode 100644 index 00000000000..d90f3713515 --- /dev/null +++ b/dag/gunbc/scm_compatibility/git.dag @@ -0,0 +1,220 @@ +module gunbc.scm_compatibility.git + +import std.types { List, NonEmptyStr } +import extdeps.git.object_store { + GitObjectId, + GitRefName, + GitRepositoryState, + GitR0Projection, + GitR0ReadBackObservation, + GitModeledRefTransition, + GitR0UnsupportedBoundary, + GitProjectionOutcome, + GitProjected, + GitReadBackOutcome, + GitReadBackVerified, + GitUpdateRefOutcome, + GitRefTransitionModeled, + git_project_repository, + git_verify_independent_read_back, + git_model_update_ref_exact, + git_object_id_content_hash, + git_r0_unsupported_boundary, +} +import gunbc.scm_compatibility_shape { + CompatibilityProjectionReceipt, + CompatibilityProjectionHandler, + CompatibilityFidelityProfile, + CompatibilityFidelityFact, + CompatibilityEndpointStateCaptured, + CompatibilityEndpointState, + CompatibilityUpstreamChangeEvidence, + CompatibilityNativeProposalContract, + CompatibilityHistory, + CompatibilityPublication, + CompatibilityConflictFacts, + CompatibilityPathAndMode, + CompatibilityAvailability, + CompatibilityNativeIdentity, + CompatibilityFidelityPreserved, + CompatibilityFidelityDowngraded, + CompatibilityFidelityUnavailable, + CompatibilityAdvanceModeled, + CompatibilityExactCompareAndAdvance, + compatibility_fidelity_profile, +} + +data git_compatibility_binding_note: NonEmptyStr = "The Git R1 handler consumes Git's own decoded projection, independent read-back, and exact-old-OID transition model. GitObjectId, GitRefName, tree/index/worktree facts, and unsupported-boundary rows remain in GitCompatibilityReceipt; the common projection contains no Git object, ref, commit, or branch type. CompatibilityAdvanceModeled is deliberately weaker than P3's executed-and-read-back transition receipt." + +type GitCompatibilityReceipt { + target: GitRefName + generation: GitObjectId + projection: GitR0Projection + read_back: GitR0ReadBackObservation + advance: GitModeledRefTransition + unsupported: List +} + +type GitCompatibilityRefusal + = GitCompatibilityProjectionRejected { outcome: GitProjectionOutcome } + | GitCompatibilityReadBackRejected { outcome: GitReadBackOutcome } + | GitCompatibilityAdvanceRejected { outcome: GitUpdateRefOutcome } + +type GitCompatibilityBindingOutcome + = GitCompatibilityBound { receipt: GitCompatibilityReceipt } + | GitCompatibilityBindingRefused { cause: GitCompatibilityRefusal } + +type GitCompatibilityBindingOutcomeFold { + bound: fn(GitCompatibilityReceipt) -> R + refused: fn(GitCompatibilityRefusal) -> R +} + +fn git_compatibility_binding_outcome_fold( + outcome: GitCompatibilityBindingOutcome, + fold: GitCompatibilityBindingOutcomeFold, +) -> R { + match outcome { + GitCompatibilityBound { receipt } => fold.bound(receipt) + GitCompatibilityBindingRefused { cause } => fold.refused(cause) + } +} + +fn git_compatibility_bind( + repository: GitRepositoryState, + tree: GitObjectId, + read_back: GitR0ReadBackObservation, + target: GitRefName, + expected_generation: GitObjectId, + proposed_generation: GitObjectId, +) -> GitCompatibilityBindingOutcome { + match git_project_repository( + repo: repository, + tree_oid: tree, + ) { + GitProjected { projection } => + match git_verify_independent_read_back( + projection: projection, + observation: read_back, + ) { + GitReadBackVerified { observation } => + match git_model_update_ref_exact( + repo: repository, + name: target, + new_oid: proposed_generation, + expected_old: expected_generation, + ) { + GitRefTransitionModeled { + repository: _, + transition, + } => + GitCompatibilityBound { + receipt: GitCompatibilityReceipt { + target: target, + generation: expected_generation, + projection: projection, + read_back: observation, + advance: transition, + unsupported: git_r0_unsupported_boundary, + }, + } + rejected => + GitCompatibilityBindingRefused { + cause: GitCompatibilityAdvanceRejected { + outcome: rejected, + }, + } + } + rejected => + GitCompatibilityBindingRefused { + cause: GitCompatibilityReadBackRejected { + outcome: rejected, + }, + } + } + rejected => + GitCompatibilityBindingRefused { + cause: GitCompatibilityProjectionRejected { + outcome: rejected, + }, + } + } +} + +fn git_compatibility_fidelity() -> CompatibilityFidelityProfile { + compatibility_fidelity_profile( + first: CompatibilityFidelityFact { + axis: CompatibilityEndpointState, + disposition: CompatibilityFidelityPreserved, + }, + remaining: [ + CompatibilityFidelityFact { + axis: CompatibilityUpstreamChangeEvidence, + disposition: CompatibilityFidelityDowngraded { + cause: "an exact Git endpoint and history do not recover an authored source operation", + }, + }, + CompatibilityFidelityFact { + axis: CompatibilityNativeProposalContract, + disposition: CompatibilityFidelityUnavailable { + cause: "ordinary Git import carries no native reads/frame/ensures proposal contract", + }, + }, + CompatibilityFidelityFact { + axis: CompatibilityHistory, + disposition: CompatibilityFidelityPreserved, + }, + CompatibilityFidelityFact { + axis: CompatibilityPublication, + disposition: CompatibilityFidelityPreserved, + }, + CompatibilityFidelityFact { + axis: CompatibilityConflictFacts, + disposition: CompatibilityFidelityUnavailable { + cause: "R0 does not promote Git conflict presentation into semantic evidence", + }, + }, + CompatibilityFidelityFact { + axis: CompatibilityPathAndMode, + disposition: CompatibilityFidelityPreserved, + }, + CompatibilityFidelityFact { + axis: CompatibilityAvailability, + disposition: CompatibilityFidelityPreserved, + }, + CompatibilityFidelityFact { + axis: CompatibilityNativeIdentity, + disposition: CompatibilityFidelityPreserved, + }, + ], + ) +} + +fn git_compatibility_projection_receipt( + receipt: GitCompatibilityReceipt, +) -> CompatibilityProjectionReceipt { + let generation = git_object_id_content_hash(oid: receipt.generation) as NonEmptyStr + let projection = git_object_id_content_hash( + oid: receipt.projection.tree_oid, + ) as NonEmptyStr + CompatibilityProjectionReceipt { + realization: "git-r0", + target: receipt.target as NonEmptyStr, + generation_evidence: generation, + capture: CompatibilityEndpointStateCaptured, + projection: projection, + read_back: concat("git-readback:", receipt.read_back.git_version), + repair: concat("git-projection-repair:", projection), + advance: CompatibilityAdvanceModeled { + guarantee: CompatibilityExactCompareAndAdvance, + }, + fidelity: git_compatibility_fidelity(), + } +} + +fn git_compatibility_projection_handler() -> CompatibilityProjectionHandler { + CompatibilityProjectionHandler { + project: fn(receipt) { + git_compatibility_projection_receipt(receipt: receipt) + }, + } +} From 31e18c6ad3400915512f6dcdbc917d208e723918 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Wed, 29 Jul 2026 03:22:23 +0000 Subject: [PATCH 03/23] WIP: business --- dag/gunbc/scm_compatibility/mercurial.dag | 266 ++++++++++++++++++++++ dag/gunbc/scm_compatibility/pijul.dag | 204 +++++++++++++++++ 2 files changed, 470 insertions(+) create mode 100644 dag/gunbc/scm_compatibility/mercurial.dag create mode 100644 dag/gunbc/scm_compatibility/pijul.dag diff --git a/dag/gunbc/scm_compatibility/mercurial.dag b/dag/gunbc/scm_compatibility/mercurial.dag new file mode 100644 index 00000000000..b45dbf52581 --- /dev/null +++ b/dag/gunbc/scm_compatibility/mercurial.dag @@ -0,0 +1,266 @@ +module gunbc.scm_compatibility.mercurial + +import std.types { List, NonEmptyStr } +import extdeps.mercurial { + MercurialNamedBranchName, + MercurialNodeId, + MercurialRepositoryProjection, + MercurialRepositoryState, + MercurialProjectionRefusal, + MercurialReadBackObservation, + MercurialConditionalAdvanceCapability, + MercurialDecoded, + MercurialDecodeRefused, + MercurialRepositoryUnavailable, + MercurialReadBackMatches, + MercurialReadBackMismatch, + MercurialReadBackInvalid, + MercurialReadBackUnavailable, + MercurialConditionalAdvanceUnavailable, + mercurial_decode_projection, + mercurial_assess_read_back, + mercurial_portable_history, + mercurial_named_branch_changesets, + mercurial_node_id_text, + mercurial_r0_conditional_advance, +} +import gunbc.scm_compatibility_shape { + CompatibilityProjectionReceipt, + CompatibilityProjectionHandler, + CompatibilityFidelityProfile, + CompatibilityFidelityFact, + CompatibilityEndpointStateCaptured, + CompatibilityEndpointState, + CompatibilityUpstreamChangeEvidence, + CompatibilityNativeProposalContract, + CompatibilityHistory, + CompatibilityPublication, + CompatibilityConflictFacts, + CompatibilityPathAndMode, + CompatibilityAvailability, + CompatibilityNativeIdentity, + CompatibilityFidelityPreserved, + CompatibilityFidelityDowngraded, + CompatibilityFidelityUnavailable, + CompatibilityAdvanceUnavailable, + compatibility_fidelity_profile, +} + +data mercurial_compatibility_binding_note: NonEmptyStr = "The Mercurial R1 handler consumes Mercurial's own projection decoder, portable changeset identities, named-branch relation, and independent read-back assessment. Clone-local revisions, phases, bookmarks, tags, evolution, repository completeness, and node identities remain in MercurialCompatibilityReceipt. The shared carrier does not rename any of them commit, ref, or branch authority, and R0 honestly reports conditional advance as unavailable." + +type MercurialCompatibilityReceipt { + target: MercurialNamedBranchName + portable_history: List + target_history: List + repository: MercurialRepositoryState + projection: MercurialRepositoryProjection + read_back: MercurialReadBackObservation + advance: MercurialConditionalAdvanceCapability +} + +type MercurialCompatibilityRefusal + = MercurialCompatibilityDecodeRejected { + cause: MercurialProjectionRefusal, + } + | MercurialCompatibilityRepositoryUnavailable { reason: NonEmptyStr } + | MercurialCompatibilityTargetMissing { + target: MercurialNamedBranchName, + } + | MercurialCompatibilityReadBackMismatch { observed_by: NonEmptyStr } + | MercurialCompatibilityReadBackInvalid { + observed_by: NonEmptyStr, + cause: MercurialProjectionRefusal, + } + | MercurialCompatibilityReadBackUnavailable { + observed_by: NonEmptyStr, + reason: NonEmptyStr, + } + +type MercurialCompatibilityBindingOutcome + = MercurialCompatibilityBound { receipt: MercurialCompatibilityReceipt } + | MercurialCompatibilityBindingRefused { + cause: MercurialCompatibilityRefusal, + } + +type MercurialCompatibilityBindingOutcomeFold { + bound: fn(MercurialCompatibilityReceipt) -> R + refused: fn(MercurialCompatibilityRefusal) -> R +} + +fn mercurial_compatibility_binding_outcome_fold( + outcome: MercurialCompatibilityBindingOutcome, + fold: MercurialCompatibilityBindingOutcomeFold, +) -> R { + match outcome { + MercurialCompatibilityBound { receipt } => fold.bound(receipt) + MercurialCompatibilityBindingRefused { cause } => fold.refused(cause) + } +} + +fn mercurial_compatibility_bind( + projection: MercurialRepositoryProjection, + target: MercurialNamedBranchName, + read_back: MercurialReadBackObservation, +) -> MercurialCompatibilityBindingOutcome { + match mercurial_decode_projection(projection: projection) { + MercurialDecodeRefused { cause } => + MercurialCompatibilityBindingRefused { + cause: MercurialCompatibilityDecodeRejected { cause: cause }, + } + MercurialRepositoryUnavailable { reason } => + MercurialCompatibilityBindingRefused { + cause: MercurialCompatibilityRepositoryUnavailable { + reason: reason, + }, + } + MercurialDecoded { repository } => { + let target_history = mercurial_named_branch_changesets( + repository: repository, + branch: target, + ) + if count(target_history) == 0 { + MercurialCompatibilityBindingRefused { + cause: MercurialCompatibilityTargetMissing { target: target }, + } + } else { + match mercurial_assess_read_back( + expected: repository, + observation: read_back, + ) { + MercurialReadBackMatches { observed_by: _ } => + MercurialCompatibilityBound { + receipt: MercurialCompatibilityReceipt { + target: target, + portable_history: mercurial_portable_history( + repository: repository, + ), + target_history: target_history, + repository: repository, + projection: projection, + read_back: read_back, + advance: mercurial_r0_conditional_advance, + }, + } + MercurialReadBackMismatch { + observed_by, + expected: _, + observed: _, + } => + MercurialCompatibilityBindingRefused { + cause: MercurialCompatibilityReadBackMismatch { + observed_by: observed_by, + }, + } + MercurialReadBackInvalid { observed_by, cause } => + MercurialCompatibilityBindingRefused { + cause: MercurialCompatibilityReadBackInvalid { + observed_by: observed_by, + cause: cause, + }, + } + MercurialReadBackUnavailable { observed_by, reason } => + MercurialCompatibilityBindingRefused { + cause: MercurialCompatibilityReadBackUnavailable { + observed_by: observed_by, + reason: reason, + }, + } + } + } + } + } +} + +fn mercurial_compatibility_history_handle( + history: List, +) -> NonEmptyStr { + concat( + "mercurial-portable-history:", + history + |> map(node => mercurial_node_id_text(node: node) as String) + |> join(separator: ","), + ) +} + +fn mercurial_compatibility_fidelity() -> CompatibilityFidelityProfile { + compatibility_fidelity_profile( + first: CompatibilityFidelityFact { + axis: CompatibilityEndpointState, + disposition: CompatibilityFidelityPreserved, + }, + remaining: [ + CompatibilityFidelityFact { + axis: CompatibilityUpstreamChangeEvidence, + disposition: CompatibilityFidelityDowngraded { + cause: "portable changeset history preserves upstream history but not the authored source operation", + }, + }, + CompatibilityFidelityFact { + axis: CompatibilityNativeProposalContract, + disposition: CompatibilityFidelityUnavailable { + cause: "Mercurial R0 carries no native reads/frame/ensures proposal contract", + }, + }, + CompatibilityFidelityFact { + axis: CompatibilityHistory, + disposition: CompatibilityFidelityPreserved, + }, + CompatibilityFidelityFact { + axis: CompatibilityPublication, + disposition: CompatibilityFidelityPreserved, + }, + CompatibilityFidelityFact { + axis: CompatibilityConflictFacts, + disposition: CompatibilityFidelityUnavailable { + cause: "Mercurial R0 does not promote merge presentation into semantic conflict evidence", + }, + }, + CompatibilityFidelityFact { + axis: CompatibilityPathAndMode, + disposition: CompatibilityFidelityPreserved, + }, + CompatibilityFidelityFact { + axis: CompatibilityAvailability, + disposition: CompatibilityFidelityPreserved, + }, + CompatibilityFidelityFact { + axis: CompatibilityNativeIdentity, + disposition: CompatibilityFidelityPreserved, + }, + ], + ) +} + +fn mercurial_compatibility_projection_receipt( + receipt: MercurialCompatibilityReceipt, +) -> CompatibilityProjectionReceipt { + let generation = mercurial_compatibility_history_handle( + history: receipt.target_history, + ) + match receipt.advance { + MercurialConditionalAdvanceUnavailable { reason } => + CompatibilityProjectionReceipt { + realization: "mercurial-r0", + target: receipt.target as NonEmptyStr, + generation_evidence: generation, + capture: CompatibilityEndpointStateCaptured, + projection: concat("mercurial-projection:", generation), + read_back: concat( + "mercurial-readback:", + receipt.read_back.observed_by, + ), + repair: concat("mercurial-projection-repair:", generation), + advance: CompatibilityAdvanceUnavailable { cause: reason }, + fidelity: mercurial_compatibility_fidelity(), + } + } +} + +fn mercurial_compatibility_projection_handler( +) -> CompatibilityProjectionHandler { + CompatibilityProjectionHandler { + project: fn(receipt) { + mercurial_compatibility_projection_receipt(receipt: receipt) + }, + } +} diff --git a/dag/gunbc/scm_compatibility/pijul.dag b/dag/gunbc/scm_compatibility/pijul.dag new file mode 100644 index 00000000000..50e77e96248 --- /dev/null +++ b/dag/gunbc/scm_compatibility/pijul.dag @@ -0,0 +1,204 @@ +module gunbc.scm_compatibility.pijul + +import std.types { NonEmptyStr } +import v2.std.optional { Present, Absent } +import extdeps.pijul { + PijulChannelName, + PijulChannelStateIdentity, + PijulRepositoryProjection, + PijulDecodedRepository, + PijulProjectionRefusal, + PijulReadBackObservation, + PijulConditionalAdvanceCapability, + PijulDecoded, + PijulDecodeRefused, + PijulReadBackMatches, + PijulReadBackMismatch, + PijulReadBackInvalid, + PijulConditionalAdvanceUnavailable, + pijul_decode_projection, + pijul_assess_read_back, + pijul_find_channel, + pijul_r0_conditional_advance, +} +import gunbc.scm_compatibility_shape { + CompatibilityProjectionReceipt, + CompatibilityProjectionHandler, + CompatibilityFidelityProfile, + CompatibilityFidelityFact, + CompatibilityUpstreamChangeEvidenceCaptured, + CompatibilityEndpointState, + CompatibilityUpstreamChangeEvidence, + CompatibilityNativeProposalContract, + CompatibilityHistory, + CompatibilityPublication, + CompatibilityConflictFacts, + CompatibilityPathAndMode, + CompatibilityAvailability, + CompatibilityNativeIdentity, + CompatibilityFidelityPreserved, + CompatibilityFidelityDowngraded, + CompatibilityFidelityUnavailable, + CompatibilityAdvanceUnavailable, + compatibility_fidelity_profile, +} + +data pijul_compatibility_binding_note: NonEmptyStr = "The Pijul R1 handler consumes Pijul's own projection decoder, channel state identity, recorded changes, dependency/context graph, graph-conflict facts, partial availability, and independent read-back assessment. Those facts remain in PijulCompatibilityReceipt. The shared target and generation handles are opaque projections only; they are not commits, refs, branches, or semantic conflict verdicts, and R0 honestly reports conditional advance as unavailable." + +type PijulCompatibilityReceipt { + target: PijulChannelName + generation: PijulChannelStateIdentity + repository: PijulDecodedRepository + projection: PijulRepositoryProjection + read_back: PijulReadBackObservation + advance: PijulConditionalAdvanceCapability +} + +type PijulCompatibilityRefusal + = PijulCompatibilityDecodeRejected { cause: PijulProjectionRefusal } + | PijulCompatibilityTargetMissing { target: PijulChannelName } + | PijulCompatibilityReadBackMismatch + | PijulCompatibilityReadBackInvalid { cause: PijulProjectionRefusal } + +type PijulCompatibilityBindingOutcome + = PijulCompatibilityBound { receipt: PijulCompatibilityReceipt } + | PijulCompatibilityBindingRefused { cause: PijulCompatibilityRefusal } + +type PijulCompatibilityBindingOutcomeFold { + bound: fn(PijulCompatibilityReceipt) -> R + refused: fn(PijulCompatibilityRefusal) -> R +} + +fn pijul_compatibility_binding_outcome_fold( + outcome: PijulCompatibilityBindingOutcome, + fold: PijulCompatibilityBindingOutcomeFold, +) -> R { + match outcome { + PijulCompatibilityBound { receipt } => fold.bound(receipt) + PijulCompatibilityBindingRefused { cause } => fold.refused(cause) + } +} + +fn pijul_compatibility_bind( + projection: PijulRepositoryProjection, + target: PijulChannelName, + read_back: PijulReadBackObservation, +) -> PijulCompatibilityBindingOutcome { + match pijul_decode_projection(projection: projection) { + PijulDecodeRefused { cause } => + PijulCompatibilityBindingRefused { + cause: PijulCompatibilityDecodeRejected { cause: cause }, + } + PijulDecoded { repository } => + match pijul_find_channel( + channels: repository.state.channels, + name: target, + ) { + Absent => + PijulCompatibilityBindingRefused { + cause: PijulCompatibilityTargetMissing { target: target }, + } + Present { value: channel } => + match pijul_assess_read_back( + expected: projection, + observation: read_back, + ) { + PijulReadBackMatches { observation: _ } => + PijulCompatibilityBound { + receipt: PijulCompatibilityReceipt { + target: target, + generation: channel.state_identity, + repository: repository, + projection: projection, + read_back: read_back, + advance: pijul_r0_conditional_advance(), + }, + } + PijulReadBackMismatch { axis: _ } => + PijulCompatibilityBindingRefused { + cause: PijulCompatibilityReadBackMismatch, + } + PijulReadBackInvalid { cause } => + PijulCompatibilityBindingRefused { + cause: PijulCompatibilityReadBackInvalid { cause: cause }, + } + } + } + } +} + +fn pijul_compatibility_fidelity() -> CompatibilityFidelityProfile { + compatibility_fidelity_profile( + first: CompatibilityFidelityFact { + axis: CompatibilityEndpointState, + disposition: CompatibilityFidelityPreserved, + }, + remaining: [ + CompatibilityFidelityFact { + axis: CompatibilityUpstreamChangeEvidence, + disposition: CompatibilityFidelityPreserved, + }, + CompatibilityFidelityFact { + axis: CompatibilityNativeProposalContract, + disposition: CompatibilityFidelityUnavailable { + cause: "Pijul recorded changes retain upstream operations and dependencies, not the native proposal's full reads/frame/ensures contract", + }, + }, + CompatibilityFidelityFact { + axis: CompatibilityHistory, + disposition: CompatibilityFidelityPreserved, + }, + CompatibilityFidelityFact { + axis: CompatibilityPublication, + disposition: CompatibilityFidelityDowngraded { + cause: "a Pijul channel is retained as native state, not promoted into the product publication policy", + }, + }, + CompatibilityFidelityFact { + axis: CompatibilityConflictFacts, + disposition: CompatibilityFidelityPreserved, + }, + CompatibilityFidelityFact { + axis: CompatibilityPathAndMode, + disposition: CompatibilityFidelityPreserved, + }, + CompatibilityFidelityFact { + axis: CompatibilityAvailability, + disposition: CompatibilityFidelityPreserved, + }, + CompatibilityFidelityFact { + axis: CompatibilityNativeIdentity, + disposition: CompatibilityFidelityPreserved, + }, + ], + ) +} + +fn pijul_compatibility_projection_receipt( + receipt: PijulCompatibilityReceipt, +) -> CompatibilityProjectionReceipt { + let generation = receipt.generation.state as NonEmptyStr + match receipt.advance { + PijulConditionalAdvanceUnavailable { reason } => + CompatibilityProjectionReceipt { + realization: "pijul-r0", + target: receipt.target as NonEmptyStr, + generation_evidence: generation, + capture: CompatibilityUpstreamChangeEvidenceCaptured, + projection: concat("pijul-channel-state:", generation), + read_back: concat("pijul-readback:", generation), + repair: concat("pijul-projection-repair:", generation), + advance: CompatibilityAdvanceUnavailable { cause: reason }, + fidelity: pijul_compatibility_fidelity(), + } + } +} + +fn pijul_compatibility_projection_handler( +) -> CompatibilityProjectionHandler { + CompatibilityProjectionHandler { + project: fn(receipt) { + pijul_compatibility_projection_receipt(receipt: receipt) + }, + } +} From b1eb8ee788e8ae8ba5ece6e5b6a90363f2ce19a7 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Wed, 29 Jul 2026 03:32:54 +0000 Subject: [PATCH 04/23] WIP: business --- dag/gunbc/native_scm_interaction_contract.dag | 129 +++++++----- ..._scm_interaction_contract_witness_test.dag | 53 ++++- .../scm_compatibility_git_witness_test.dag | 184 ++++++++++++++++++ ...m_compatibility_mercurial_witness_test.dag | 162 +++++++++++++++ .../scm_compatibility_pijul_witness_test.dag | 162 +++++++++++++++ .../scm_compatibility_shape_witness_test.dag | 124 ++++++++++++ 6 files changed, 750 insertions(+), 64 deletions(-) create mode 100644 dag/test/claim/scm_compatibility_git_witness_test.dag create mode 100644 dag/test/claim/scm_compatibility_mercurial_witness_test.dag create mode 100644 dag/test/claim/scm_compatibility_pijul_witness_test.dag create mode 100644 dag/test/claim/scm_compatibility_shape_witness_test.dag diff --git a/dag/gunbc/native_scm_interaction_contract.dag b/dag/gunbc/native_scm_interaction_contract.dag index e306c5e5da1..7a771b55341 100644 --- a/dag/gunbc/native_scm_interaction_contract.dag +++ b/dag/gunbc/native_scm_interaction_contract.dag @@ -2,8 +2,12 @@ module gunbc.native_scm_interaction_contract import std.types { Bool, Int, List, String } import v2.std.optional { Optional, Present, Absent, optional_present, optional_absent } +import gunbc.scm_compatibility_shape { + CompatibilityProjectionReceipt, + compatibility_projection_upsert, +} -data native_scm_interaction_contract_note: String = "Model-first contract carrier for the native SCM interaction slice. The model stays on the presentation side of the split: a proposal has a stable identity, the user-facing primary outcome is Landed | ChoiceRequired | CouldNotLand, review/access/check/operational remain orthogonal fields, and workspace/target/git projections stay optional. No engine, transport, or CLI lives here; the witnesses exercise the contract as a black-box surface." +data native_scm_interaction_contract_note: String = "Model-first contract carrier for the native SCM interaction slice. The model stays on the presentation side of the split: a proposal has a stable identity, the user-facing primary outcome is Landed | ChoiceRequired | CouldNotLand, review/access/check/operational remain orthogonal fields, workspace/target context stays optional, and compatibility projections are indexed by realization and target rather than a Git-only slot. No engine, semantic admission, transport, or CLI lives here; the witnesses exercise the contract as a black-box surface." type NativeScmProposalIdentity { name: String @@ -22,7 +26,7 @@ type NativeScmLifecycle type NativeScmProjection { workspace: Optional target: Optional - git: Optional + realizations: List } type NativeScmContinuation { @@ -152,11 +156,11 @@ fn native_scm_transition_for(scenario: NativeScmScenario) -> NativeScmCommitTran } } -fn native_scm_projection(workspace: String, target: String, git: String) -> NativeScmProjection { +fn native_scm_projection(workspace: String, target: String) -> NativeScmProjection { NativeScmProjection { workspace: optional_present(value: workspace), target: optional_present(value: target), - git: optional_present(value: git), + realizations: [], } } @@ -331,58 +335,48 @@ fn native_scm_receipt_for(scenario: NativeScmScenario) -> NativeScmReceipt { GitExportFailureRepairsWithoutReinterpretation => NativeScmProjection { workspace: optional_present(value: "/workspaces/native-scm-export-repair"), target: optional_present(value: "main"), - git: optional_absent(), + realizations: [], } ConventionalGitImportWithoutRebase => native_scm_projection( workspace: "/workspaces/native-scm-import", target: "main", - git: "origin/session/native-scm-import", ) - TwoIndependentChangesLand => NativeScmProjection { - workspace: optional_present(value: "/workspaces/native-scm-contract"), - target: optional_present(value: "main"), - git: optional_present(value: "origin/main"), - } - StaleTargetAutoResync => NativeScmProjection { - workspace: optional_present(value: "/workspaces/native-scm-contract"), - target: optional_present(value: "main"), - git: optional_present(value: "origin/main"), - } - DuplicateSubmissionAppliesOnce => NativeScmProjection { - workspace: optional_present(value: "/workspaces/native-scm-contract"), - target: optional_present(value: "main"), - git: optional_present(value: "origin/main"), - } - RenameReferenceUniqueMeaning => NativeScmProjection { - workspace: optional_present(value: "/workspaces/native-scm-contract"), - target: optional_present(value: "main"), - git: optional_present(value: "origin/main"), - } - TwoLegitimateMeaningsNeedChoice => NativeScmProjection { - workspace: optional_present(value: "/workspaces/native-scm-contract"), - target: optional_present(value: "main"), - git: optional_present(value: "origin/main"), - } - IncompatibleGoalsNeedAuthorizedDecider => NativeScmProjection { - workspace: optional_present(value: "/workspaces/native-scm-contract"), - target: optional_present(value: "main"), - git: optional_present(value: "origin/main"), - } - EvidenceGatheredInternally => NativeScmProjection { - workspace: optional_present(value: "/workspaces/native-scm-contract"), - target: optional_present(value: "main"), - git: optional_present(value: "origin/main"), - } - ToolModelProofDeficitRoutesInternally => NativeScmProjection { - workspace: optional_present(value: "/workspaces/native-scm-contract"), - target: optional_present(value: "main"), - git: optional_present(value: "origin/main"), - } - VisibilityAuthorizedDetails => NativeScmProjection { - workspace: optional_present(value: "/workspaces/native-scm-contract"), - target: optional_present(value: "main"), - git: optional_present(value: "origin/main"), - } + TwoIndependentChangesLand => native_scm_projection( + workspace: "/workspaces/native-scm-contract", + target: "main", + ) + StaleTargetAutoResync => native_scm_projection( + workspace: "/workspaces/native-scm-contract", + target: "main", + ) + DuplicateSubmissionAppliesOnce => native_scm_projection( + workspace: "/workspaces/native-scm-contract", + target: "main", + ) + RenameReferenceUniqueMeaning => native_scm_projection( + workspace: "/workspaces/native-scm-contract", + target: "main", + ) + TwoLegitimateMeaningsNeedChoice => native_scm_projection( + workspace: "/workspaces/native-scm-contract", + target: "main", + ) + IncompatibleGoalsNeedAuthorizedDecider => native_scm_projection( + workspace: "/workspaces/native-scm-contract", + target: "main", + ) + EvidenceGatheredInternally => native_scm_projection( + workspace: "/workspaces/native-scm-contract", + target: "main", + ) + ToolModelProofDeficitRoutesInternally => native_scm_projection( + workspace: "/workspaces/native-scm-contract", + target: "main", + ) + VisibilityAuthorizedDetails => native_scm_projection( + workspace: "/workspaces/native-scm-contract", + target: "main", + ) }, primary: native_scm_primary_for(scenario: scenario, identity: identity), receipt_details: native_scm_receipt_details_for(scenario: scenario), @@ -458,24 +452,51 @@ fn native_scm_resolve_choice( } } -fn native_scm_repair_git_projection(receipt: NativeScmReceipt, git_ref: String) -> NativeScmReceipt { +fn native_scm_attach_projection( + receipt: NativeScmReceipt, + projection: CompatibilityProjectionReceipt, +) -> NativeScmReceipt { NativeScmReceipt { identity: receipt.identity, transition: receipt.transition, review: receipt.review, access: receipt.access, check: receipt.check, - operational: NativeScmLifecycleReady, + operational: receipt.operational, projections: NativeScmProjection { workspace: receipt.projections.workspace, target: receipt.projections.target, - git: optional_present(value: git_ref), + realizations: compatibility_projection_upsert( + existing: receipt.projections.realizations, + projection: projection, + ), }, primary: receipt.primary, receipt_details: receipt.receipt_details, } } +fn native_scm_repair_projection( + receipt: NativeScmReceipt, + projection: CompatibilityProjectionReceipt, +) -> NativeScmReceipt { + let attached = native_scm_attach_projection( + receipt: receipt, + projection: projection, + ) + NativeScmReceipt { + identity: attached.identity, + transition: attached.transition, + review: attached.review, + access: attached.access, + check: attached.check, + operational: NativeScmLifecycleReady, + projections: attached.projections, + primary: attached.primary, + receipt_details: attached.receipt_details, + } +} + fn native_scm_inspect_receipt(receipt: NativeScmReceipt, authorized: Bool) -> Optional { if authorized { match receipt.receipt_details { diff --git a/dag/test/claim/native_scm_interaction_contract_witness_test.dag b/dag/test/claim/native_scm_interaction_contract_witness_test.dag index f4d47901151..a416e16a7d2 100644 --- a/dag/test/claim/native_scm_interaction_contract_witness_test.dag +++ b/dag/test/claim/native_scm_interaction_contract_witness_test.dag @@ -20,13 +20,22 @@ import gunbc.native_scm_interaction_contract { native_scm_receipt_for, native_scm_primary_label, native_scm_resolve_choice, - native_scm_repair_git_projection, + native_scm_repair_projection, native_scm_inspect_receipt, native_scm_submission_ledger, native_scm_apply_once, native_scm_applied_count, native_scm_rekey_receipt, } +import gunbc.scm_compatibility_shape { + CompatibilityProjectionReceipt, + CompatibilityFidelityFact, + CompatibilityEndpointStateCaptured, + CompatibilityEndpointState, + CompatibilityFidelityPreserved, + CompatibilityAdvanceUnavailable, + compatibility_fidelity_profile, +} data live_tree_disposition: LiveTreeDisposition = SubstrateInputsOnly @@ -38,6 +47,28 @@ fn primary_label(receipt: NativeScmReceipt) -> String { native_scm_primary_label(primary: receipt.primary) } +fn fixture_compatibility_projection() -> CompatibilityProjectionReceipt { + CompatibilityProjectionReceipt { + realization: "git-r0", + target: "refs/heads/main", + generation_evidence: "git-generation-fixture", + capture: CompatibilityEndpointStateCaptured, + projection: "git-projection-fixture", + read_back: "git-readback-fixture", + repair: "git-repair-fixture", + advance: CompatibilityAdvanceUnavailable { + cause: "C0 witness does not establish an executing transition", + }, + fidelity: compatibility_fidelity_profile( + first: CompatibilityFidelityFact { + axis: CompatibilityEndpointState, + disposition: CompatibilityFidelityPreserved, + }, + remaining: [], + ), + } +} + test fn witness_two_independent_changes_both_land() -> Bool { let r = receipt_for(scenario: TwoIndependentChangesLand) primary_label(receipt: r) == "Landed" @@ -156,17 +187,19 @@ test fn witness_tool_model_proof_deficits_stay_internal() -> Bool { test fn witness_git_export_failure_repairs_without_reinterpretation() -> Bool { let r = receipt_for(scenario: GitExportFailureRepairsWithoutReinterpretation) - let repaired = native_scm_repair_git_projection(receipt: r, git_ref: "origin/main") + let repaired = native_scm_repair_projection( + receipt: r, + projection: fixture_compatibility_projection(), + ) primary_label(receipt: r) == "Landed" && primary_label(receipt: repaired) == "Landed" - && match r.projections.git { - Absent => true - Present { value: _ } => false - } - && match repaired.projections.git { - Present { value: git_ref } => git_ref == "origin/main" - Absent => false - } + && count(r.projections.realizations) == 0 + && count(repaired.projections.realizations) == 1 + && repaired.projections.realizations + |> any(row => + row.realization == "git-r0" + && row.target == "refs/heads/main" + ) } test fn witness_conventional_git_import_without_rebase() -> Bool { diff --git a/dag/test/claim/scm_compatibility_git_witness_test.dag b/dag/test/claim/scm_compatibility_git_witness_test.dag new file mode 100644 index 00000000000..6a68b9d666a --- /dev/null +++ b/dag/test/claim/scm_compatibility_git_witness_test.dag @@ -0,0 +1,184 @@ +module test.claim.scm_compatibility_git_witness + +import std.types { Bool } +import v2.std.live_tree { LiveTreeDisposition, SubstrateInputsOnly } +import extdeps.git.object_store { + GitR0ReadBackObservation, +} +import test.claim.git_upstream_model_witness { + fixture_repository, + fixture_read_back_observation, + sha1_root_tree, + sha1_parent_commit, + sha1_next_commit, +} +import gunbc.scm_compatibility.git { + GitCompatibilityBindingOutcome, + GitCompatibilityBound, + GitCompatibilityBindingRefused, + git_compatibility_bind, + git_compatibility_projection_handler, + git_compatibility_projection_receipt, +} +import gunbc.scm_compatibility_shape { + CompatibilityUpstreamChangeEvidence, + CompatibilityFidelityDowngraded, + CompatibilityAdvanceModeled, + CompatibilityExactCompareAndAdvance, + CompatibilityObservationOnly, + CompatibilityModeledAdvanceRequired, + CompatibilityExecutedAdvanceRequired, + CompatibilityCapabilitySatisfied, + CompatibilityCapabilityRefused, + compatibility_projection_from_handler, + compatibility_check_advance_requirement, +} +import gunbc.native_scm_interaction_contract { + TwoIndependentChangesLand, + native_scm_receipt_for, + native_scm_primary_label, + native_scm_attach_projection, +} + +data live_tree_disposition: LiveTreeDisposition = SubstrateInputsOnly + +fn git_fixture_binding() -> GitCompatibilityBindingOutcome { + git_compatibility_bind( + repository: fixture_repository(), + tree: sha1_root_tree, + read_back: fixture_read_back_observation(), + target: "refs/heads/main", + expected_generation: sha1_parent_commit, + proposed_generation: sha1_next_commit, + ) +} + +test fn witness_git_r1_consumes_native_projection_readback_and_advance() -> Bool { + match git_fixture_binding() { + GitCompatibilityBindingRefused { cause: _ } => false + GitCompatibilityBound { receipt } => + receipt.target == "refs/heads/main" + && receipt.generation == sha1_parent_commit + && count(receipt.unsupported) > 0 + && match git_compatibility_projection_receipt(receipt: receipt).advance { + CompatibilityAdvanceModeled { guarantee } => + guarantee == CompatibilityExactCompareAndAdvance + _ => false + } + } +} + +test fn witness_git_realization_preserves_c0_primary_behavior() -> Bool { + let original = native_scm_receipt_for( + scenario: TwoIndependentChangesLand, + ) + match git_fixture_binding() { + GitCompatibilityBindingRefused { cause: _ } => false + GitCompatibilityBound { receipt } => { + let projection = compatibility_projection_from_handler( + handler: git_compatibility_projection_handler(), + receipt: receipt, + ) + let attached = native_scm_attach_projection( + receipt: original, + projection: projection, + ) + attached.identity == original.identity + && attached.transition == original.transition + && attached.primary == original.primary + && native_scm_primary_label(primary: attached.primary) == "Landed" + && count(attached.projections.realizations) == 1 + && projection.realization == "git-r0" + } + } +} + +test fn witness_git_modeled_advance_is_not_executed_advance() -> Bool { + match git_fixture_binding() { + GitCompatibilityBindingRefused { cause: _ } => false + GitCompatibilityBound { receipt } => { + let capability = git_compatibility_projection_receipt( + receipt: receipt, + ).advance + match compatibility_check_advance_requirement( + requirement: CompatibilityObservationOnly, + observed: capability, + ) { + CompatibilityCapabilitySatisfied => + match compatibility_check_advance_requirement( + requirement: CompatibilityModeledAdvanceRequired { + guarantee: CompatibilityExactCompareAndAdvance, + }, + observed: capability, + ) { + CompatibilityCapabilitySatisfied => + match compatibility_check_advance_requirement( + requirement: CompatibilityExecutedAdvanceRequired { + guarantee: CompatibilityExactCompareAndAdvance, + }, + observed: capability, + ) { + CompatibilityCapabilityRefused { + requirement: _, + observed: _, + } => true + CompatibilityCapabilitySatisfied => false + } + CompatibilityCapabilityRefused { + requirement: _, + observed: _, + } => false + } + CompatibilityCapabilityRefused { + requirement: _, + observed: _, + } => false + } + } + } +} + +test fn witness_git_endpoint_does_not_claim_authored_operation() -> Bool { + match git_fixture_binding() { + GitCompatibilityBindingRefused { cause: _ } => false + GitCompatibilityBound { receipt } => { + let profile = git_compatibility_projection_receipt( + receipt: receipt, + ).fidelity + profile.remaining + |> any(fact => + fact.axis == CompatibilityUpstreamChangeEvidence + && match fact.disposition { + CompatibilityFidelityDowngraded { cause: _ } => true + _ => false + } + ) + } + } +} + +test fn witness_git_readback_mismatch_refuses_binding() -> Bool { + let observed = fixture_read_back_observation() + let wrong = GitR0ReadBackObservation { + git_version: observed.git_version, + object_format: observed.object_format, + tree_oid: sha1_parent_commit, + tree_entries: observed.tree_entries, + tag_oids: observed.tag_oids, + refs: observed.refs, + index: observed.index, + worktree: observed.worktree, + unavailable: observed.unavailable, + } + match git_compatibility_bind( + repository: fixture_repository(), + tree: sha1_root_tree, + read_back: wrong, + target: "refs/heads/main", + expected_generation: sha1_parent_commit, + proposed_generation: sha1_next_commit, + ) { + GitCompatibilityBindingRefused { cause: _ } => true + GitCompatibilityBound { receipt: _ } => false + } +} diff --git a/dag/test/claim/scm_compatibility_mercurial_witness_test.dag b/dag/test/claim/scm_compatibility_mercurial_witness_test.dag new file mode 100644 index 00000000000..7abcde05db5 --- /dev/null +++ b/dag/test/claim/scm_compatibility_mercurial_witness_test.dag @@ -0,0 +1,162 @@ +module test.claim.scm_compatibility_mercurial_witness + +import std.types { Bool } +import v2.std.live_tree { LiveTreeDisposition, SubstrateInputsOnly } +import extdeps.mercurial { + MercurialReadBackObservation, + MercurialInaccessibleProjection, +} +import test.claim.mercurial_upstream_model_witness { + fixture_projection, +} +import gunbc.scm_compatibility.mercurial { + MercurialCompatibilityBindingOutcome, + MercurialCompatibilityBound, + MercurialCompatibilityBindingRefused, + mercurial_compatibility_bind, + mercurial_compatibility_projection_handler, + mercurial_compatibility_projection_receipt, +} +import gunbc.scm_compatibility_shape { + CompatibilityUpstreamChangeEvidence, + CompatibilityFidelityDowngraded, + CompatibilityAdvanceUnavailable, + CompatibilityObservationOnly, + CompatibilityModeledAdvanceRequired, + CompatibilityExactCompareAndAdvance, + CompatibilityCapabilitySatisfied, + CompatibilityCapabilityRefused, + compatibility_projection_from_handler, + compatibility_check_advance_requirement, +} +import gunbc.native_scm_interaction_contract { + TwoIndependentChangesLand, + native_scm_receipt_for, + native_scm_primary_label, + native_scm_attach_projection, +} + +data live_tree_disposition: LiveTreeDisposition = SubstrateInputsOnly + +fn mercurial_fixture_observation() -> MercurialReadBackObservation { + MercurialReadBackObservation { + projection: fixture_projection(), + observed_by: "mercurial-r1-independent-fixture", + } +} + +fn mercurial_fixture_binding() -> MercurialCompatibilityBindingOutcome { + mercurial_compatibility_bind( + projection: fixture_projection(), + target: "default", + read_back: mercurial_fixture_observation(), + ) +} + +test fn witness_mercurial_r1_consumes_native_projection_and_readback() -> Bool { + match mercurial_fixture_binding() { + MercurialCompatibilityBindingRefused { cause: _ } => false + MercurialCompatibilityBound { receipt } => + receipt.target == "default" + && count(receipt.portable_history) == 3 + && count(receipt.target_history) == 3 + && match mercurial_compatibility_projection_receipt( + receipt: receipt, + ).advance { + CompatibilityAdvanceUnavailable { cause: _ } => true + _ => false + } + } +} + +test fn witness_mercurial_realization_preserves_c0_primary_behavior() -> Bool { + let original = native_scm_receipt_for( + scenario: TwoIndependentChangesLand, + ) + match mercurial_fixture_binding() { + MercurialCompatibilityBindingRefused { cause: _ } => false + MercurialCompatibilityBound { receipt } => { + let projection = compatibility_projection_from_handler( + handler: mercurial_compatibility_projection_handler(), + receipt: receipt, + ) + let attached = native_scm_attach_projection( + receipt: original, + projection: projection, + ) + attached.identity == original.identity + && attached.transition == original.transition + && attached.primary == original.primary + && native_scm_primary_label(primary: attached.primary) == "Landed" + && projection.realization == "mercurial-r0" + } + } +} + +test fn witness_mercurial_missing_advance_refuses_required_capability() -> Bool { + match mercurial_fixture_binding() { + MercurialCompatibilityBindingRefused { cause: _ } => false + MercurialCompatibilityBound { receipt } => { + let capability = mercurial_compatibility_projection_receipt( + receipt: receipt, + ).advance + match compatibility_check_advance_requirement( + requirement: CompatibilityObservationOnly, + observed: capability, + ) { + CompatibilityCapabilitySatisfied => + match compatibility_check_advance_requirement( + requirement: CompatibilityModeledAdvanceRequired { + guarantee: CompatibilityExactCompareAndAdvance, + }, + observed: capability, + ) { + CompatibilityCapabilityRefused { + requirement: _, + observed: _, + } => true + CompatibilityCapabilitySatisfied => false + } + CompatibilityCapabilityRefused { + requirement: _, + observed: _, + } => false + } + } + } +} + +test fn witness_mercurial_history_does_not_claim_authored_operation() -> Bool { + match mercurial_fixture_binding() { + MercurialCompatibilityBindingRefused { cause: _ } => false + MercurialCompatibilityBound { receipt } => { + let profile = mercurial_compatibility_projection_receipt( + receipt: receipt, + ).fidelity + profile.remaining + |> any(fact => + fact.axis == CompatibilityUpstreamChangeEvidence + && match fact.disposition { + CompatibilityFidelityDowngraded { cause: _ } => true + _ => false + } + ) + } + } +} + +test fn witness_mercurial_unavailable_readback_refuses_binding() -> Bool { + match mercurial_compatibility_bind( + projection: fixture_projection(), + target: "default", + read_back: MercurialReadBackObservation { + projection: MercurialInaccessibleProjection { + reason: "fixture unavailable", + }, + observed_by: "mercurial-r1-independent-fixture", + }, + ) { + MercurialCompatibilityBindingRefused { cause: _ } => true + MercurialCompatibilityBound { receipt: _ } => false + } +} diff --git a/dag/test/claim/scm_compatibility_pijul_witness_test.dag b/dag/test/claim/scm_compatibility_pijul_witness_test.dag new file mode 100644 index 00000000000..1d88d2a3b4c --- /dev/null +++ b/dag/test/claim/scm_compatibility_pijul_witness_test.dag @@ -0,0 +1,162 @@ +module test.claim.scm_compatibility_pijul_witness + +import std.types { Bool } +import v2.std.live_tree { LiveTreeDisposition, SubstrateInputsOnly } +import extdeps.pijul { + PijulReadBackObservation, + PijulInaccessibleProjection, + pijul_upstream_version, +} +import test.claim.pijul_upstream_model_witness { + fixture_projection, +} +import gunbc.scm_compatibility.pijul { + PijulCompatibilityBindingOutcome, + PijulCompatibilityBound, + PijulCompatibilityBindingRefused, + pijul_compatibility_bind, + pijul_compatibility_projection_handler, + pijul_compatibility_projection_receipt, +} +import gunbc.scm_compatibility_shape { + CompatibilityUpstreamChangeEvidence, + CompatibilityFidelityPreserved, + CompatibilityAdvanceUnavailable, + CompatibilityObservationOnly, + CompatibilityModeledAdvanceRequired, + CompatibilityExactCompareAndAdvance, + CompatibilityCapabilitySatisfied, + CompatibilityCapabilityRefused, + compatibility_projection_from_handler, + compatibility_check_advance_requirement, +} +import gunbc.native_scm_interaction_contract { + TwoIndependentChangesLand, + native_scm_receipt_for, + native_scm_primary_label, + native_scm_attach_projection, +} + +data live_tree_disposition: LiveTreeDisposition = SubstrateInputsOnly + +fn pijul_fixture_observation() -> PijulReadBackObservation { + PijulReadBackObservation { + pijul_version: pijul_upstream_version, + projection: fixture_projection(), + } +} + +fn pijul_fixture_binding() -> PijulCompatibilityBindingOutcome { + pijul_compatibility_bind( + projection: fixture_projection(), + target: "main", + read_back: pijul_fixture_observation(), + ) +} + +test fn witness_pijul_r1_consumes_native_projection_and_readback() -> Bool { + match pijul_fixture_binding() { + PijulCompatibilityBindingRefused { cause: _ } => false + PijulCompatibilityBound { receipt } => + receipt.target == "main" + && count(receipt.generation.changes) == 3 + && match pijul_compatibility_projection_receipt( + receipt: receipt, + ).advance { + CompatibilityAdvanceUnavailable { cause: _ } => true + _ => false + } + } +} + +test fn witness_pijul_realization_preserves_c0_primary_behavior() -> Bool { + let original = native_scm_receipt_for( + scenario: TwoIndependentChangesLand, + ) + match pijul_fixture_binding() { + PijulCompatibilityBindingRefused { cause: _ } => false + PijulCompatibilityBound { receipt } => { + let projection = compatibility_projection_from_handler( + handler: pijul_compatibility_projection_handler(), + receipt: receipt, + ) + let attached = native_scm_attach_projection( + receipt: original, + projection: projection, + ) + attached.identity == original.identity + && attached.transition == original.transition + && attached.primary == original.primary + && native_scm_primary_label(primary: attached.primary) == "Landed" + && projection.realization == "pijul-r0" + } + } +} + +test fn witness_pijul_missing_advance_refuses_required_capability() -> Bool { + match pijul_fixture_binding() { + PijulCompatibilityBindingRefused { cause: _ } => false + PijulCompatibilityBound { receipt } => { + let capability = pijul_compatibility_projection_receipt( + receipt: receipt, + ).advance + match compatibility_check_advance_requirement( + requirement: CompatibilityObservationOnly, + observed: capability, + ) { + CompatibilityCapabilitySatisfied => + match compatibility_check_advance_requirement( + requirement: CompatibilityModeledAdvanceRequired { + guarantee: CompatibilityExactCompareAndAdvance, + }, + observed: capability, + ) { + CompatibilityCapabilityRefused { + requirement: _, + observed: _, + } => true + CompatibilityCapabilitySatisfied => false + } + CompatibilityCapabilityRefused { + requirement: _, + observed: _, + } => false + } + } + } +} + +test fn witness_pijul_preserves_upstream_change_evidence() -> Bool { + match pijul_fixture_binding() { + PijulCompatibilityBindingRefused { cause: _ } => false + PijulCompatibilityBound { receipt } => { + let profile = pijul_compatibility_projection_receipt( + receipt: receipt, + ).fidelity + profile.remaining + |> any(fact => + fact.axis == CompatibilityUpstreamChangeEvidence + && match fact.disposition { + CompatibilityFidelityPreserved => true + _ => false + } + ) + } + } +} + +test fn witness_pijul_unavailable_readback_refuses_binding() -> Bool { + match pijul_compatibility_bind( + projection: fixture_projection(), + target: "main", + read_back: PijulReadBackObservation { + pijul_version: pijul_upstream_version, + projection: PijulInaccessibleProjection { + reason: "fixture unavailable", + }, + }, + ) { + PijulCompatibilityBindingRefused { cause: _ } => true + PijulCompatibilityBound { receipt: _ } => false + } +} diff --git a/dag/test/claim/scm_compatibility_shape_witness_test.dag b/dag/test/claim/scm_compatibility_shape_witness_test.dag new file mode 100644 index 00000000000..2b86114585b --- /dev/null +++ b/dag/test/claim/scm_compatibility_shape_witness_test.dag @@ -0,0 +1,124 @@ +module test.claim.scm_compatibility_shape_witness + +import std.types { Bool, NonEmptyStr } +import v2.std.live_tree { LiveTreeDisposition, SubstrateInputsOnly } +import gunbc.scm_compatibility_shape { + CompatibilityProjectionReceipt, + CompatibilityProjectionHandler, + CompatibilityFidelityFact, + CompatibilityEndpointStateCaptured, + CompatibilityEndpointState, + CompatibilityFidelityPreserved, + CompatibilityAdvanceUnavailable, + compatibility_fidelity_profile, + compatibility_projection_from_handler, +} +import gunbc.native_scm_interaction_contract { + TwoIndependentChangesLand, + native_scm_receipt_for, + native_scm_primary_label, + native_scm_attach_projection, +} + +data live_tree_disposition: LiveTreeDisposition = SubstrateInputsOnly + +type SyntheticFourthReceipt { + target: NonEmptyStr + generation: NonEmptyStr +} + +fn synthetic_fourth_handler( +) -> CompatibilityProjectionHandler { + CompatibilityProjectionHandler { + project: fn(receipt) { + CompatibilityProjectionReceipt { + realization: "synthetic-fourth-r0", + target: receipt.target, + generation_evidence: receipt.generation, + capture: CompatibilityEndpointStateCaptured, + projection: concat("synthetic-projection:", receipt.generation), + read_back: concat("synthetic-readback:", receipt.generation), + repair: concat("synthetic-repair:", receipt.generation), + advance: CompatibilityAdvanceUnavailable { + cause: "synthetic R0 intentionally has no conditional advance", + }, + fidelity: compatibility_fidelity_profile( + first: CompatibilityFidelityFact { + axis: CompatibilityEndpointState, + disposition: CompatibilityFidelityPreserved, + }, + remaining: [], + ), + } + }, + } +} + +fn synthetic_projection( + target: NonEmptyStr, + generation: NonEmptyStr, +) -> CompatibilityProjectionReceipt { + compatibility_projection_from_handler( + handler: synthetic_fourth_handler(), + receipt: SyntheticFourthReceipt { + target: target, + generation: generation, + }, + ) +} + +test fn witness_fourth_realization_adds_handler_without_primary_edit() -> Bool { + let original = native_scm_receipt_for( + scenario: TwoIndependentChangesLand, + ) + let projected = synthetic_projection( + target: "main", + generation: "synthetic-generation-1", + ) + let attached = native_scm_attach_projection( + receipt: original, + projection: projected, + ) + attached.identity == original.identity + && attached.transition == original.transition + && attached.primary == original.primary + && native_scm_primary_label(primary: attached.primary) == "Landed" + && count(attached.projections.realizations) == 1 + && attached.projections.realizations + |> any(row => row.realization == "synthetic-fourth-r0") +} + +test fn witness_projection_attachment_is_idempotent_per_realization_target() -> Bool { + let original = native_scm_receipt_for( + scenario: TwoIndependentChangesLand, + ) + let first = native_scm_attach_projection( + receipt: original, + projection: synthetic_projection( + target: "main", + generation: "synthetic-generation-1", + ), + ) + let replaced = native_scm_attach_projection( + receipt: first, + projection: synthetic_projection( + target: "main", + generation: "synthetic-generation-2", + ), + ) + let second_target = native_scm_attach_projection( + receipt: replaced, + projection: synthetic_projection( + target: "review", + generation: "synthetic-generation-3", + ), + ) + count(first.projections.realizations) == 1 + && count(replaced.projections.realizations) == 1 + && replaced.projections.realizations + |> any(row => + row.target == "main" + && row.generation_evidence == "synthetic-generation-2" + ) + && count(second_target.projections.realizations) == 2 +} From 58775f2f8d4efe2d6c20d314074ad533954e36a9 Mon Sep 17 00:00:00 2001 From: gunbc-ci-auto-heal Date: Wed, 29 Jul 2026 19:19:29 +0000 Subject: [PATCH 05/23] WIP: business --- dag/gunbc/native_scm_interaction_contract.dag | 60 ++++++++-------- dag/gunbc/roadmap_authority.dag | 68 ++++-------------- dag/gunbc/scm_compatibility/git.dag | 72 +++++-------------- dag/gunbc/scm_compatibility/mercurial.dag | 72 +++++-------------- dag/gunbc/scm_compatibility/pijul.dag | 68 ++++-------------- dag/gunbc/scm_compatibility_shape.dag | 37 +++------- ..._scm_interaction_contract_witness_test.dag | 52 +++++++++----- dag/test/claim/roadmap_authority_test.dag | 14 ++-- .../scm_compatibility_git_witness_test.dag | 13 ++-- ...m_compatibility_mercurial_witness_test.dag | 13 ++-- .../scm_compatibility_pijul_witness_test.dag | 13 ++-- .../scm_compatibility_shape_witness_test.dag | 37 +++++++--- docs/plans/dag-scm-design.md | 19 ++--- 13 files changed, 191 insertions(+), 347 deletions(-) diff --git a/dag/gunbc/native_scm_interaction_contract.dag b/dag/gunbc/native_scm_interaction_contract.dag index 7a771b55341..919e9e656d0 100644 --- a/dag/gunbc/native_scm_interaction_contract.dag +++ b/dag/gunbc/native_scm_interaction_contract.dag @@ -83,8 +83,8 @@ type NativeScmScenario | IncompatibleGoalsNeedAuthorizedDecider | EvidenceGatheredInternally | ToolModelProofDeficitRoutesInternally - | GitExportFailureRepairsWithoutReinterpretation - | ConventionalGitImportWithoutRebase + | ProjectionFailureRepairsWithoutReinterpretation + | ConventionalScmImportWithoutManualRewrite | VisibilityAuthorizedDetails fn native_scm_identity_for(scenario: NativeScmScenario) -> NativeScmProposalIdentity { @@ -121,13 +121,13 @@ fn native_scm_identity_for(scenario: NativeScmScenario) -> NativeScmProposalIden name: "tool-model-proof-deficit-routes-internally", attempt_key: "attempt-tool-model-proof-deficit", } - GitExportFailureRepairsWithoutReinterpretation => NativeScmProposalIdentity { - name: "git-export-failure-repairs-without-reinterpretation", - attempt_key: "attempt-git-export-failure", + ProjectionFailureRepairsWithoutReinterpretation => NativeScmProposalIdentity { + name: "projection-failure-repairs-without-reinterpretation", + attempt_key: "attempt-projection-failure", } - ConventionalGitImportWithoutRebase => NativeScmProposalIdentity { - name: "conventional-git-import-without-rebase", - attempt_key: "attempt-conventional-git-import", + ConventionalScmImportWithoutManualRewrite => NativeScmProposalIdentity { + name: "conventional-scm-import-without-manual-rewrite", + attempt_key: "attempt-conventional-scm-import", } VisibilityAuthorizedDetails => NativeScmProposalIdentity { name: "visibility-authorized-details", @@ -150,8 +150,8 @@ fn native_scm_transition_for(scenario: NativeScmScenario) -> NativeScmCommitTran DuplicateSubmissionAppliesOnce => NativeScmCommitTransitionCommitted RenameReferenceUniqueMeaning => NativeScmCommitTransitionCommitted EvidenceGatheredInternally => NativeScmCommitTransitionCommitted - GitExportFailureRepairsWithoutReinterpretation => NativeScmCommitTransitionCommitted - ConventionalGitImportWithoutRebase => NativeScmCommitTransitionCommitted + ProjectionFailureRepairsWithoutReinterpretation => NativeScmCommitTransitionCommitted + ConventionalScmImportWithoutManualRewrite => NativeScmCommitTransitionCommitted VisibilityAuthorizedDetails => NativeScmCommitTransitionCommitted } } @@ -208,11 +208,11 @@ fn native_scm_primary_for(scenario: NativeScmScenario, identity: NativeScmPropos ToolModelProofDeficitRoutesInternally => InProgress { progress_preview: "tool, model, and proof work remain internal; the proposal is still progressing", } - GitExportFailureRepairsWithoutReinterpretation => Landed { - result_preview: "accepted result remains landed while the Git export projection is repaired separately", + ProjectionFailureRepairsWithoutReinterpretation => Landed { + result_preview: "accepted result remains landed while its compatibility projection is repaired separately", } - ConventionalGitImportWithoutRebase => Landed { - result_preview: "a conventional Git branch import lands as an ordinary import with no manual rewrite", + ConventionalScmImportWithoutManualRewrite => Landed { + result_preview: "a conventional SCM import lands as an ordinary import with no manual synchronization rewrite", } VisibilityAuthorizedDetails => Landed { result_preview: "details stay optional and can be projected only when visibility authorizes them", @@ -246,11 +246,11 @@ fn native_scm_receipt_details_for(scenario: NativeScmScenario) -> Optional Present { value: "details: internal progress stays internal until the machine finishes its own continuation", } - GitExportFailureRepairsWithoutReinterpretation => Present { - value: "details: Git export repair updates only the projection, not the semantic result", + ProjectionFailureRepairsWithoutReinterpretation => Present { + value: "details: compatibility repair updates only the projection, not the semantic result", } - ConventionalGitImportWithoutRebase => Present { - value: "details: import is accepted as a normal branch import with the ordinary projection", + ConventionalScmImportWithoutManualRewrite => Present { + value: "details: import is accepted through its native realization without a manual synchronization rewrite", } VisibilityAuthorizedDetails => Present { value: "details: this text is only available when visibility authorizes it", @@ -268,8 +268,8 @@ fn native_scm_review_for(scenario: NativeScmScenario) -> NativeScmLifecycle { TwoLegitimateMeaningsNeedChoice => NativeScmLifecycleReady IncompatibleGoalsNeedAuthorizedDecider => NativeScmLifecycleReady EvidenceGatheredInternally => NativeScmLifecycleReady - GitExportFailureRepairsWithoutReinterpretation => NativeScmLifecycleReady - ConventionalGitImportWithoutRebase => NativeScmLifecycleReady + ProjectionFailureRepairsWithoutReinterpretation => NativeScmLifecycleReady + ConventionalScmImportWithoutManualRewrite => NativeScmLifecycleReady VisibilityAuthorizedDetails => NativeScmLifecycleReady } } @@ -284,8 +284,8 @@ fn native_scm_access_for(scenario: NativeScmScenario) -> NativeScmLifecycle { TwoLegitimateMeaningsNeedChoice => NativeScmLifecycleReady IncompatibleGoalsNeedAuthorizedDecider => NativeScmLifecycleReady EvidenceGatheredInternally => NativeScmLifecycleReady - GitExportFailureRepairsWithoutReinterpretation => NativeScmLifecycleReady - ConventionalGitImportWithoutRebase => NativeScmLifecycleReady + ProjectionFailureRepairsWithoutReinterpretation => NativeScmLifecycleReady + ConventionalScmImportWithoutManualRewrite => NativeScmLifecycleReady VisibilityAuthorizedDetails => NativeScmLifecycleReady } } @@ -300,15 +300,15 @@ fn native_scm_check_for(scenario: NativeScmScenario) -> NativeScmLifecycle { TwoLegitimateMeaningsNeedChoice => NativeScmLifecycleReady IncompatibleGoalsNeedAuthorizedDecider => NativeScmLifecycleReady EvidenceGatheredInternally => NativeScmLifecycleReady - GitExportFailureRepairsWithoutReinterpretation => NativeScmLifecycleReady - ConventionalGitImportWithoutRebase => NativeScmLifecycleReady + ProjectionFailureRepairsWithoutReinterpretation => NativeScmLifecycleReady + ConventionalScmImportWithoutManualRewrite => NativeScmLifecycleReady VisibilityAuthorizedDetails => NativeScmLifecycleReady } } fn native_scm_operational_for(scenario: NativeScmScenario) -> NativeScmLifecycle { match scenario { - GitExportFailureRepairsWithoutReinterpretation => NativeScmLifecyclePending + ProjectionFailureRepairsWithoutReinterpretation => NativeScmLifecyclePending ToolModelProofDeficitRoutesInternally => NativeScmLifecyclePending TwoIndependentChangesLand => NativeScmLifecycleReady StaleTargetAutoResync => NativeScmLifecycleReady @@ -317,7 +317,7 @@ fn native_scm_operational_for(scenario: NativeScmScenario) -> NativeScmLifecycle TwoLegitimateMeaningsNeedChoice => NativeScmLifecycleReady IncompatibleGoalsNeedAuthorizedDecider => NativeScmLifecycleReady EvidenceGatheredInternally => NativeScmLifecycleReady - ConventionalGitImportWithoutRebase => NativeScmLifecycleReady + ConventionalScmImportWithoutManualRewrite => NativeScmLifecycleReady VisibilityAuthorizedDetails => NativeScmLifecycleReady } } @@ -332,13 +332,13 @@ fn native_scm_receipt_for(scenario: NativeScmScenario) -> NativeScmReceipt { check: native_scm_check_for(scenario: scenario), operational: native_scm_operational_for(scenario: scenario), projections: match scenario { - GitExportFailureRepairsWithoutReinterpretation => NativeScmProjection { - workspace: optional_present(value: "/workspaces/native-scm-export-repair"), + ProjectionFailureRepairsWithoutReinterpretation => NativeScmProjection { + workspace: optional_present(value: "/workspaces/native-scm-projection-repair"), target: optional_present(value: "main"), realizations: [], } - ConventionalGitImportWithoutRebase => native_scm_projection( - workspace: "/workspaces/native-scm-import", + ConventionalScmImportWithoutManualRewrite => native_scm_projection( + workspace: "/workspaces/native-scm-conventional-import", target: "main", ) TwoIndependentChangesLand => native_scm_projection( diff --git a/dag/gunbc/roadmap_authority.dag b/dag/gunbc/roadmap_authority.dag index 191df349333..d82ddac1758 100644 --- a/dag/gunbc/roadmap_authority.dag +++ b/dag/gunbc/roadmap_authority.dag @@ -369,67 +369,19 @@ fn caret_parse_smoke_seed_growth_fields(j: SeedGrowthJustification) -> TicketFie fn declared_roadmap_nodes() -> List { [ active_sized( - id: "2-scm-git-upstream-model", + id: "2-scm-compatibility-shape", owner: "source-intent", path: "docs/plans/dag-scm-design.md", intricacy: IntricacyHigh, volume: VolumeMedium, t: fields( - headline: "Write down how Git really stores things", - boundary: "Describe Git on its own terms: files, folders, commits, tags, file permissions, symlinks, links to other repositories, and how it names and finds them. Prove it by reading a small repository and writing it back unchanged.", - displaced_cost: "If we invent a one-size-fits-all model first, it quietly drops things like executable permissions and symlinks — and every tool built on top inherits the loss.", - first_slice: "Finish the storage description, then read one small repository and write it back unchanged.", - red_control: "A plain file, an executable file, a symlink, a link to another repository, and a tag all stay distinguishable; writing against an out-of-date starting point refuses instead of overwriting; a missing object never reads as empty.", - out_of_scope: "No shared source-control interface, no hosting or server work, and no guessing that a renamed file is the same file.", - handback: "The model with citations to Git's own docs, the read/write-back receipts, the refusal receipt, and a list of anything we still cannot represent." - ) - ), - active_sized( - id: "2-scm-mercurial-upstream-model", - owner: "source-intent", - path: "docs/plans/dag-scm-design.md", - intricacy: IntricacyHigh, - volume: VolumeMedium, - t: fields( - headline: "Write down how Mercurial really works, in its own words", - boundary: "Describe Mercurial from its own documentation: its permanent change IDs versus the numbers local to one copy, its branches, bookmarks, tags, and its draft/published states. Use no Git vocabulary.", - displaced_cost: "Mercurial's ideas are not Git's. Renaming them into Git words loses the differences, and a later shared design would be built on a mistranslation.", - first_slice: "Write the description and read one small repository back out, leaving anything we cannot safely write marked unavailable.", - red_control: "A copy-local revision number can change while the permanent change ID does not; draft, published, and hidden stay three different things; a bookmark, a named branch, and a branch tip cannot collapse into one idea.", - out_of_scope: "No Mercurial support in the product, no shared source-control interface, and no faking missing facts from timestamps.", - handback: "The description with citations, the read-back receipt, an explicit list of what we cannot do yet, and the differences that must survive into any later shared design." - ) - ), - active_sized( - id: "2-scm-pijul-upstream-model", - owner: "source-intent", - path: "docs/plans/dag-scm-design.md", - intricacy: IntricacyHigh, - volume: VolumeMedium, - t: fields( - headline: "Write down how Pijul really works, in its own words", - boundary: "Describe Pijul from its own documentation: individual changes that carry their own identity, what each change depends on, and how a channel is a set of changes rather than a pointer to the newest one.", - displaced_cost: "Pijul does not have a 'latest commit'. Modelling it as if it does erases the thing that makes it different, and a third viewpoint is what stops us from mistaking Git's habits for universal truth.", - first_slice: "Write the description, then apply a small set of changes, read them back, and try them in a different order.", - red_control: "A channel cannot be reduced to one newest commit; one change keeps the same identity in two channels; applying a change whose prerequisites are missing refuses instead of applying an empty change.", - out_of_scope: "No Pijul support in the product, no adopting its conflict rules as ours, and no shared source-control interface.", - handback: "The description with citations, the round-trip and out-of-order receipts, and an explicit list of what we cannot do yet." - ) - ), - active_sized( - id: "2-claim-indexed-evidence", - owner: "deduction", - path: "docs/plans/dag-scm-design.md", - intricacy: IntricacyHigh, - volume: VolumeMedium, - t: fields( - headline: "Say once what counts as evidence for a claim", - boundary: "One shared way to record a fact, state a claim, and link evidence that supports or contradicts it — including how much a piece of evidence can prove on its own. Three existing features adopt it.", - displaced_cost: "Right now each feature invents its own yes/no test, so a weak signal gets promoted into a confident claim. 'We stored a login' starts meaning 'the login works'.", - first_slice: "Reuse what already exists for this, then run it through the three features that need it and check they agree.", - red_control: "A stored login plus a failed live request supports 'we have a credential' but not 'the service is ready'; contradictory evidence stays contradictory and missing evidence stays missing, rather than the newest answer winning.", - out_of_scope: "No source-control solver, no per-feature copy of the idea, and no treating 'we recorded this' as proof that it is true.", - handback: "The shared model, receipts from all three features, the supports/contradicts/both/neither cases, and anything the substrate still cannot express." + headline: "Extract the compatibility realization shape from three upstream receipts", + boundary: "Consume the independently executing Git, Mercurial, and Pijul R0 boundaries and extract only their demonstrated roles: opaque target/generation handles, capture class, fidelity profile, projection/read-back/repair identity, and explicit conditional-advance capability. Native receipts retain every upstream-specific fact; dispatch is a generic handler value, never ScmKind or a vendor switch.", + displaced_cost: "Lets the native edit → submit → outcome contract project through plural SCMs without forcing users into Git mechanics or erasing Mercurial/Pijul distinctions into a first-adapter abstraction.", + first_slice: "Bind each R0 fixture through its native decoder and read-back assessment, replace C0's optional Git projection slot with realization-indexed receipts, and execute one fixed C0 proposal through Git, Mercurial, Pijul, and a synthetic fourth handler.", + red_control: "C0 proposal identity, transition, and primary outcome stay unchanged across all realizations; missing required conditional advance refuses; modeled Git advance cannot satisfy executed advance; a read-back mismatch refuses; the fourth handler requires no primary-contract or kernel edit.", + out_of_scope: "No semantic candidate space, admission policy, Applied receipt, universal commit/ref/channel type, hosted service, writable Mercurial/Pijul target, or central realization enum.", + handback: "Return the shared role carrier, three native adapter receipts, fidelity/capability matrix, realization-indexed C0 projection, idempotent repair receipt, and the exact distinctions deliberately left native." ) ), @@ -1413,7 +1365,11 @@ fn active_section_for(focus: RoadmapFocus) -> RoadmapSection { title: "Active deliverables — dependency order", elements: concat( [ +<<<<<<< HEAD section_prose(content: "The graph has ten lanes: SCM prerequisites · namespace · P-derive · observation · placement · v1 exit (four finish lines: compiler fixed point, interpreter deleted, products v1-free, zero hand-maintained Rust) · shell · roadmap runtime · fleet/hygiene · hermetic toolchain. The three SCM R0 models, the P−1 evidence carrier, and the toolchain pin model are independent roots; compatibility extraction and later SCM/product lanes remain parked. The P-derive receipt feeds the emitter fixed point, so the v1 chain nests under it. Node fields define boundary, first slice, RED control, exclusions, owner, and handback."), +======= + section_prose(content: "The graph has nine lanes: SCM compatibility · namespace · P-derive · observation · placement · v1 exit (four finish lines: compiler fixed point, interpreter deleted, products v1-free, zero hand-maintained Rust) · shell · roadmap runtime · fleet/hygiene. The three independent SCM R0 models and P−1 evidence carrier are landed prerequisites; R1 compatibility-shape extraction is the active SCM slice, while semantic-kernel and later product lanes remain parked. The P-derive receipt feeds the emitter fixed point, so the v1 chain nests under it. Node fields define boundary, first slice, RED control, exclusions, owner, and handback."), +>>>>>>> fa45abd9601 (WIP: business) ], concat( if focus_is_active(focus: focus) { diff --git a/dag/gunbc/scm_compatibility/git.dag b/dag/gunbc/scm_compatibility/git.dag index d90f3713515..7d61d7bb9a2 100644 --- a/dag/gunbc/scm_compatibility/git.dag +++ b/dag/gunbc/scm_compatibility/git.dag @@ -25,23 +25,12 @@ import gunbc.scm_compatibility_shape { CompatibilityProjectionReceipt, CompatibilityProjectionHandler, CompatibilityFidelityProfile, - CompatibilityFidelityFact, CompatibilityEndpointStateCaptured, - CompatibilityEndpointState, - CompatibilityUpstreamChangeEvidence, - CompatibilityNativeProposalContract, - CompatibilityHistory, - CompatibilityPublication, - CompatibilityConflictFacts, - CompatibilityPathAndMode, - CompatibilityAvailability, - CompatibilityNativeIdentity, CompatibilityFidelityPreserved, CompatibilityFidelityDowngraded, CompatibilityFidelityUnavailable, CompatibilityAdvanceModeled, CompatibilityExactCompareAndAdvance, - compatibility_fidelity_profile, } data git_compatibility_binding_note: NonEmptyStr = "The Git R1 handler consumes Git's own decoded projection, independent read-back, and exact-old-OID transition model. GitObjectId, GitRefName, tree/index/worktree facts, and unsupported-boundary rows remain in GitCompatibilityReceipt; the common projection contains no Git object, ref, commit, or branch type. CompatibilityAdvanceModeled is deliberately weaker than P3's executed-and-read-back transition receipt." @@ -141,52 +130,23 @@ fn git_compatibility_bind( } fn git_compatibility_fidelity() -> CompatibilityFidelityProfile { - compatibility_fidelity_profile( - first: CompatibilityFidelityFact { - axis: CompatibilityEndpointState, - disposition: CompatibilityFidelityPreserved, + CompatibilityFidelityProfile { + endpoint_state: CompatibilityFidelityPreserved, + upstream_change_evidence: CompatibilityFidelityDowngraded { + cause: "an exact Git endpoint and history do not recover an authored source operation", }, - remaining: [ - CompatibilityFidelityFact { - axis: CompatibilityUpstreamChangeEvidence, - disposition: CompatibilityFidelityDowngraded { - cause: "an exact Git endpoint and history do not recover an authored source operation", - }, - }, - CompatibilityFidelityFact { - axis: CompatibilityNativeProposalContract, - disposition: CompatibilityFidelityUnavailable { - cause: "ordinary Git import carries no native reads/frame/ensures proposal contract", - }, - }, - CompatibilityFidelityFact { - axis: CompatibilityHistory, - disposition: CompatibilityFidelityPreserved, - }, - CompatibilityFidelityFact { - axis: CompatibilityPublication, - disposition: CompatibilityFidelityPreserved, - }, - CompatibilityFidelityFact { - axis: CompatibilityConflictFacts, - disposition: CompatibilityFidelityUnavailable { - cause: "R0 does not promote Git conflict presentation into semantic evidence", - }, - }, - CompatibilityFidelityFact { - axis: CompatibilityPathAndMode, - disposition: CompatibilityFidelityPreserved, - }, - CompatibilityFidelityFact { - axis: CompatibilityAvailability, - disposition: CompatibilityFidelityPreserved, - }, - CompatibilityFidelityFact { - axis: CompatibilityNativeIdentity, - disposition: CompatibilityFidelityPreserved, - }, - ], - ) + native_proposal_contract: CompatibilityFidelityUnavailable { + cause: "ordinary Git import carries no native reads/frame/ensures proposal contract", + }, + history: CompatibilityFidelityPreserved, + publication: CompatibilityFidelityPreserved, + conflict_facts: CompatibilityFidelityUnavailable { + cause: "R0 does not promote Git conflict presentation into semantic evidence", + }, + path_and_mode: CompatibilityFidelityPreserved, + availability: CompatibilityFidelityPreserved, + native_identity: CompatibilityFidelityPreserved, + } } fn git_compatibility_projection_receipt( diff --git a/dag/gunbc/scm_compatibility/mercurial.dag b/dag/gunbc/scm_compatibility/mercurial.dag index b45dbf52581..ae28bf83ec5 100644 --- a/dag/gunbc/scm_compatibility/mercurial.dag +++ b/dag/gunbc/scm_compatibility/mercurial.dag @@ -28,22 +28,11 @@ import gunbc.scm_compatibility_shape { CompatibilityProjectionReceipt, CompatibilityProjectionHandler, CompatibilityFidelityProfile, - CompatibilityFidelityFact, CompatibilityEndpointStateCaptured, - CompatibilityEndpointState, - CompatibilityUpstreamChangeEvidence, - CompatibilityNativeProposalContract, - CompatibilityHistory, - CompatibilityPublication, - CompatibilityConflictFacts, - CompatibilityPathAndMode, - CompatibilityAvailability, - CompatibilityNativeIdentity, CompatibilityFidelityPreserved, CompatibilityFidelityDowngraded, CompatibilityFidelityUnavailable, CompatibilityAdvanceUnavailable, - compatibility_fidelity_profile, } data mercurial_compatibility_binding_note: NonEmptyStr = "The Mercurial R1 handler consumes Mercurial's own projection decoder, portable changeset identities, named-branch relation, and independent read-back assessment. Clone-local revisions, phases, bookmarks, tags, evolution, repository completeness, and node identities remain in MercurialCompatibilityReceipt. The shared carrier does not rename any of them commit, ref, or branch authority, and R0 honestly reports conditional advance as unavailable." @@ -183,52 +172,23 @@ fn mercurial_compatibility_history_handle( } fn mercurial_compatibility_fidelity() -> CompatibilityFidelityProfile { - compatibility_fidelity_profile( - first: CompatibilityFidelityFact { - axis: CompatibilityEndpointState, - disposition: CompatibilityFidelityPreserved, + CompatibilityFidelityProfile { + endpoint_state: CompatibilityFidelityPreserved, + upstream_change_evidence: CompatibilityFidelityDowngraded { + cause: "portable changeset history preserves upstream history but not the authored source operation", }, - remaining: [ - CompatibilityFidelityFact { - axis: CompatibilityUpstreamChangeEvidence, - disposition: CompatibilityFidelityDowngraded { - cause: "portable changeset history preserves upstream history but not the authored source operation", - }, - }, - CompatibilityFidelityFact { - axis: CompatibilityNativeProposalContract, - disposition: CompatibilityFidelityUnavailable { - cause: "Mercurial R0 carries no native reads/frame/ensures proposal contract", - }, - }, - CompatibilityFidelityFact { - axis: CompatibilityHistory, - disposition: CompatibilityFidelityPreserved, - }, - CompatibilityFidelityFact { - axis: CompatibilityPublication, - disposition: CompatibilityFidelityPreserved, - }, - CompatibilityFidelityFact { - axis: CompatibilityConflictFacts, - disposition: CompatibilityFidelityUnavailable { - cause: "Mercurial R0 does not promote merge presentation into semantic conflict evidence", - }, - }, - CompatibilityFidelityFact { - axis: CompatibilityPathAndMode, - disposition: CompatibilityFidelityPreserved, - }, - CompatibilityFidelityFact { - axis: CompatibilityAvailability, - disposition: CompatibilityFidelityPreserved, - }, - CompatibilityFidelityFact { - axis: CompatibilityNativeIdentity, - disposition: CompatibilityFidelityPreserved, - }, - ], - ) + native_proposal_contract: CompatibilityFidelityUnavailable { + cause: "Mercurial R0 carries no native reads/frame/ensures proposal contract", + }, + history: CompatibilityFidelityPreserved, + publication: CompatibilityFidelityPreserved, + conflict_facts: CompatibilityFidelityUnavailable { + cause: "Mercurial R0 does not promote merge presentation into semantic conflict evidence", + }, + path_and_mode: CompatibilityFidelityPreserved, + availability: CompatibilityFidelityPreserved, + native_identity: CompatibilityFidelityPreserved, + } } fn mercurial_compatibility_projection_receipt( diff --git a/dag/gunbc/scm_compatibility/pijul.dag b/dag/gunbc/scm_compatibility/pijul.dag index 50e77e96248..cab686d6d21 100644 --- a/dag/gunbc/scm_compatibility/pijul.dag +++ b/dag/gunbc/scm_compatibility/pijul.dag @@ -25,22 +25,11 @@ import gunbc.scm_compatibility_shape { CompatibilityProjectionReceipt, CompatibilityProjectionHandler, CompatibilityFidelityProfile, - CompatibilityFidelityFact, CompatibilityUpstreamChangeEvidenceCaptured, - CompatibilityEndpointState, - CompatibilityUpstreamChangeEvidence, - CompatibilityNativeProposalContract, - CompatibilityHistory, - CompatibilityPublication, - CompatibilityConflictFacts, - CompatibilityPathAndMode, - CompatibilityAvailability, - CompatibilityNativeIdentity, CompatibilityFidelityPreserved, CompatibilityFidelityDowngraded, CompatibilityFidelityUnavailable, CompatibilityAdvanceUnavailable, - compatibility_fidelity_profile, } data pijul_compatibility_binding_note: NonEmptyStr = "The Pijul R1 handler consumes Pijul's own projection decoder, channel state identity, recorded changes, dependency/context graph, graph-conflict facts, partial availability, and independent read-back assessment. Those facts remain in PijulCompatibilityReceipt. The shared target and generation handles are opaque projections only; they are not commits, refs, branches, or semantic conflict verdicts, and R0 honestly reports conditional advance as unavailable." @@ -128,50 +117,21 @@ fn pijul_compatibility_bind( } fn pijul_compatibility_fidelity() -> CompatibilityFidelityProfile { - compatibility_fidelity_profile( - first: CompatibilityFidelityFact { - axis: CompatibilityEndpointState, - disposition: CompatibilityFidelityPreserved, + CompatibilityFidelityProfile { + endpoint_state: CompatibilityFidelityPreserved, + upstream_change_evidence: CompatibilityFidelityPreserved, + native_proposal_contract: CompatibilityFidelityUnavailable { + cause: "Pijul recorded changes retain upstream operations and dependencies, not the native proposal's full reads/frame/ensures contract", }, - remaining: [ - CompatibilityFidelityFact { - axis: CompatibilityUpstreamChangeEvidence, - disposition: CompatibilityFidelityPreserved, - }, - CompatibilityFidelityFact { - axis: CompatibilityNativeProposalContract, - disposition: CompatibilityFidelityUnavailable { - cause: "Pijul recorded changes retain upstream operations and dependencies, not the native proposal's full reads/frame/ensures contract", - }, - }, - CompatibilityFidelityFact { - axis: CompatibilityHistory, - disposition: CompatibilityFidelityPreserved, - }, - CompatibilityFidelityFact { - axis: CompatibilityPublication, - disposition: CompatibilityFidelityDowngraded { - cause: "a Pijul channel is retained as native state, not promoted into the product publication policy", - }, - }, - CompatibilityFidelityFact { - axis: CompatibilityConflictFacts, - disposition: CompatibilityFidelityPreserved, - }, - CompatibilityFidelityFact { - axis: CompatibilityPathAndMode, - disposition: CompatibilityFidelityPreserved, - }, - CompatibilityFidelityFact { - axis: CompatibilityAvailability, - disposition: CompatibilityFidelityPreserved, - }, - CompatibilityFidelityFact { - axis: CompatibilityNativeIdentity, - disposition: CompatibilityFidelityPreserved, - }, - ], - ) + history: CompatibilityFidelityPreserved, + publication: CompatibilityFidelityDowngraded { + cause: "a Pijul channel is retained as native state, not promoted into the product publication policy", + }, + conflict_facts: CompatibilityFidelityPreserved, + path_and_mode: CompatibilityFidelityPreserved, + availability: CompatibilityFidelityPreserved, + native_identity: CompatibilityFidelityPreserved, + } } fn pijul_compatibility_projection_receipt( diff --git a/dag/gunbc/scm_compatibility_shape.dag b/dag/gunbc/scm_compatibility_shape.dag index 5dbc033265f..8a2892aa286 100644 --- a/dag/gunbc/scm_compatibility_shape.dag +++ b/dag/gunbc/scm_compatibility_shape.dag @@ -33,17 +33,6 @@ fn compatibility_capture_class_fold( } } -type CompatibilityFidelityAxis - = CompatibilityEndpointState - | CompatibilityUpstreamChangeEvidence - | CompatibilityNativeProposalContract - | CompatibilityHistory - | CompatibilityPublication - | CompatibilityConflictFacts - | CompatibilityPathAndMode - | CompatibilityAvailability - | CompatibilityNativeIdentity - type CompatibilityFidelityDisposition = CompatibilityFidelityPreserved | CompatibilityFidelityDowngraded { cause: NonEmptyStr } @@ -66,24 +55,16 @@ fn compatibility_fidelity_disposition_fold( } } -type CompatibilityFidelityFact { - axis: CompatibilityFidelityAxis - disposition: CompatibilityFidelityDisposition -} - type CompatibilityFidelityProfile { - first: CompatibilityFidelityFact - remaining: List -} - -fn compatibility_fidelity_profile( - first: CompatibilityFidelityFact, - remaining: List, -) -> CompatibilityFidelityProfile { - CompatibilityFidelityProfile { - first: first, - remaining: remaining, - } + endpoint_state: CompatibilityFidelityDisposition + upstream_change_evidence: CompatibilityFidelityDisposition + native_proposal_contract: CompatibilityFidelityDisposition + history: CompatibilityFidelityDisposition + publication: CompatibilityFidelityDisposition + conflict_facts: CompatibilityFidelityDisposition + path_and_mode: CompatibilityFidelityDisposition + availability: CompatibilityFidelityDisposition + native_identity: CompatibilityFidelityDisposition } type CompatibilityAdvanceGuarantee diff --git a/dag/test/claim/native_scm_interaction_contract_witness_test.dag b/dag/test/claim/native_scm_interaction_contract_witness_test.dag index a416e16a7d2..330f54ae438 100644 --- a/dag/test/claim/native_scm_interaction_contract_witness_test.dag +++ b/dag/test/claim/native_scm_interaction_contract_witness_test.dag @@ -14,8 +14,8 @@ import gunbc.native_scm_interaction_contract { IncompatibleGoalsNeedAuthorizedDecider, EvidenceGatheredInternally, ToolModelProofDeficitRoutesInternally, - GitExportFailureRepairsWithoutReinterpretation, - ConventionalGitImportWithoutRebase, + ProjectionFailureRepairsWithoutReinterpretation, + ConventionalScmImportWithoutManualRewrite, VisibilityAuthorizedDetails, native_scm_receipt_for, native_scm_primary_label, @@ -29,12 +29,11 @@ import gunbc.native_scm_interaction_contract { } import gunbc.scm_compatibility_shape { CompatibilityProjectionReceipt, - CompatibilityFidelityFact, + CompatibilityFidelityProfile, CompatibilityEndpointStateCaptured, - CompatibilityEndpointState, CompatibilityFidelityPreserved, + CompatibilityFidelityUnavailable, CompatibilityAdvanceUnavailable, - compatibility_fidelity_profile, } data live_tree_disposition: LiveTreeDisposition = SubstrateInputsOnly @@ -59,13 +58,33 @@ fn fixture_compatibility_projection() -> CompatibilityProjectionReceipt { advance: CompatibilityAdvanceUnavailable { cause: "C0 witness does not establish an executing transition", }, - fidelity: compatibility_fidelity_profile( - first: CompatibilityFidelityFact { - axis: CompatibilityEndpointState, - disposition: CompatibilityFidelityPreserved, + fidelity: CompatibilityFidelityProfile { + endpoint_state: CompatibilityFidelityPreserved, + upstream_change_evidence: CompatibilityFidelityUnavailable { + cause: "C0 fixture does not carry authored-change evidence", }, - remaining: [], - ), + native_proposal_contract: CompatibilityFidelityUnavailable { + cause: "C0 fixture does not carry a proposal contract", + }, + history: CompatibilityFidelityUnavailable { + cause: "C0 fixture does not carry history", + }, + publication: CompatibilityFidelityUnavailable { + cause: "C0 fixture does not carry publication facts", + }, + conflict_facts: CompatibilityFidelityUnavailable { + cause: "C0 fixture does not carry conflict facts", + }, + path_and_mode: CompatibilityFidelityUnavailable { + cause: "C0 fixture does not carry path or mode facts", + }, + availability: CompatibilityFidelityUnavailable { + cause: "C0 fixture does not carry availability facts", + }, + native_identity: CompatibilityFidelityUnavailable { + cause: "C0 fixture does not carry native identity", + }, + }, } } @@ -185,8 +204,8 @@ test fn witness_tool_model_proof_deficits_stay_internal() -> Bool { } } -test fn witness_git_export_failure_repairs_without_reinterpretation() -> Bool { - let r = receipt_for(scenario: GitExportFailureRepairsWithoutReinterpretation) +test fn witness_projection_failure_repairs_without_reinterpretation() -> Bool { + let r = receipt_for(scenario: ProjectionFailureRepairsWithoutReinterpretation) let repaired = native_scm_repair_projection( receipt: r, projection: fixture_compatibility_projection(), @@ -202,12 +221,13 @@ test fn witness_git_export_failure_repairs_without_reinterpretation() -> Bool { ) } -test fn witness_conventional_git_import_without_rebase() -> Bool { - let r = receipt_for(scenario: ConventionalGitImportWithoutRebase) +test fn witness_conventional_scm_import_without_manual_rewrite() -> Bool { + let r = receipt_for(scenario: ConventionalScmImportWithoutManualRewrite) primary_label(receipt: r) == "Landed" && match r.primary { Landed { result_preview } => - !string_contains(s: result_preview, pattern: "rebase") + !string_contains(s: result_preview, pattern: "Git") + && !string_contains(s: result_preview, pattern: "rebase") _ => false } } diff --git a/dag/test/claim/roadmap_authority_test.dag b/dag/test/claim/roadmap_authority_test.dag index 0f9162079d4..92c80ffea21 100644 --- a/dag/test/claim/roadmap_authority_test.dag +++ b/dag/test/claim/roadmap_authority_test.dag @@ -509,7 +509,7 @@ test fn witness_product_roots_have_no_false_roadmap_tool_dependency() -> Bool { data scm_prerequisite_witness_focus_note: String = "Projected UNFOCUSED deliberately. This claim is about which lanes the AUTHORITY declares active, and it happens to read the markdown to check it. Left on the focused projection it would silently become a claim about the current view — going red whenever someone focused the page, reporting a roadmap defect where none exists. NoFocus keeps the claim measuring what it names." -test fn witness_only_requested_scm_prerequisites_are_active() -> Bool { +test fn witness_only_requested_scm_compatibility_slice_is_active() -> Bool { let out = serialize_markdown_source( doc: project_roadmap_to_markdown( doc: roadmap_authority_for(focus: NoFocus), @@ -520,14 +520,14 @@ test fn witness_only_requested_scm_prerequisites_are_active() -> Bool { && string_contains(s: out, pattern: "(docs/plans/dag-scm-product-strategy.md)") && string_contains(s: out, pattern: "(docs/plans/node-subtree-visibility-grants.md)") && node_has_carrier_path(path: "docs/plans/dag-scm-design.md") - && node_count_with_carrier_path(path: "docs/plans/dag-scm-design.md") == 4 + && node_count_with_carrier_path(path: "docs/plans/dag-scm-design.md") == 1 && !node_has_carrier_path(path: "docs/plans/dag-scm-product-strategy.md") && !node_has_carrier_path(path: "docs/plans/node-subtree-visibility-grants.md") - && id_exists(id: "2-scm-git-upstream-model") - && id_exists(id: "2-scm-mercurial-upstream-model") - && id_exists(id: "2-scm-pijul-upstream-model") - && id_exists(id: "2-claim-indexed-evidence") - && !id_exists(id: "2-scm-compatibility-shape") + && !id_exists(id: "2-scm-git-upstream-model") + && !id_exists(id: "2-scm-mercurial-upstream-model") + && !id_exists(id: "2-scm-pijul-upstream-model") + && !id_exists(id: "2-claim-indexed-evidence") + && id_exists(id: "2-scm-compatibility-shape") && !id_exists(id: "2-scm-node-merge") && !id_exists(id: "2-scm-design-partner-shadow") } diff --git a/dag/test/claim/scm_compatibility_git_witness_test.dag b/dag/test/claim/scm_compatibility_git_witness_test.dag index 6a68b9d666a..ced38142c1a 100644 --- a/dag/test/claim/scm_compatibility_git_witness_test.dag +++ b/dag/test/claim/scm_compatibility_git_witness_test.dag @@ -21,7 +21,6 @@ import gunbc.scm_compatibility.git { git_compatibility_projection_receipt, } import gunbc.scm_compatibility_shape { - CompatibilityUpstreamChangeEvidence, CompatibilityFidelityDowngraded, CompatibilityAdvanceModeled, CompatibilityExactCompareAndAdvance, @@ -145,14 +144,10 @@ test fn witness_git_endpoint_does_not_claim_authored_operation() -> Bool { let profile = git_compatibility_projection_receipt( receipt: receipt, ).fidelity - profile.remaining - |> any(fact => - fact.axis == CompatibilityUpstreamChangeEvidence - && match fact.disposition { - CompatibilityFidelityDowngraded { cause: _ } => true - _ => false - } - ) + match profile.upstream_change_evidence { + CompatibilityFidelityDowngraded { cause: _ } => true + _ => false + } } } } diff --git a/dag/test/claim/scm_compatibility_mercurial_witness_test.dag b/dag/test/claim/scm_compatibility_mercurial_witness_test.dag index 7abcde05db5..e96c0d0e8d3 100644 --- a/dag/test/claim/scm_compatibility_mercurial_witness_test.dag +++ b/dag/test/claim/scm_compatibility_mercurial_witness_test.dag @@ -18,7 +18,6 @@ import gunbc.scm_compatibility.mercurial { mercurial_compatibility_projection_receipt, } import gunbc.scm_compatibility_shape { - CompatibilityUpstreamChangeEvidence, CompatibilityFidelityDowngraded, CompatibilityAdvanceUnavailable, CompatibilityObservationOnly, @@ -133,14 +132,10 @@ test fn witness_mercurial_history_does_not_claim_authored_operation() -> Bool { let profile = mercurial_compatibility_projection_receipt( receipt: receipt, ).fidelity - profile.remaining - |> any(fact => - fact.axis == CompatibilityUpstreamChangeEvidence - && match fact.disposition { - CompatibilityFidelityDowngraded { cause: _ } => true - _ => false - } - ) + match profile.upstream_change_evidence { + CompatibilityFidelityDowngraded { cause: _ } => true + _ => false + } } } } diff --git a/dag/test/claim/scm_compatibility_pijul_witness_test.dag b/dag/test/claim/scm_compatibility_pijul_witness_test.dag index 1d88d2a3b4c..70641ab3bc8 100644 --- a/dag/test/claim/scm_compatibility_pijul_witness_test.dag +++ b/dag/test/claim/scm_compatibility_pijul_witness_test.dag @@ -19,7 +19,6 @@ import gunbc.scm_compatibility.pijul { pijul_compatibility_projection_receipt, } import gunbc.scm_compatibility_shape { - CompatibilityUpstreamChangeEvidence, CompatibilityFidelityPreserved, CompatibilityAdvanceUnavailable, CompatibilityObservationOnly, @@ -133,14 +132,10 @@ test fn witness_pijul_preserves_upstream_change_evidence() -> Bool { let profile = pijul_compatibility_projection_receipt( receipt: receipt, ).fidelity - profile.remaining - |> any(fact => - fact.axis == CompatibilityUpstreamChangeEvidence - && match fact.disposition { - CompatibilityFidelityPreserved => true - _ => false - } - ) + match profile.upstream_change_evidence { + CompatibilityFidelityPreserved => true + _ => false + } } } } diff --git a/dag/test/claim/scm_compatibility_shape_witness_test.dag b/dag/test/claim/scm_compatibility_shape_witness_test.dag index 2b86114585b..e9d04a20b57 100644 --- a/dag/test/claim/scm_compatibility_shape_witness_test.dag +++ b/dag/test/claim/scm_compatibility_shape_witness_test.dag @@ -5,12 +5,11 @@ import v2.std.live_tree { LiveTreeDisposition, SubstrateInputsOnly } import gunbc.scm_compatibility_shape { CompatibilityProjectionReceipt, CompatibilityProjectionHandler, - CompatibilityFidelityFact, + CompatibilityFidelityProfile, CompatibilityEndpointStateCaptured, - CompatibilityEndpointState, CompatibilityFidelityPreserved, + CompatibilityFidelityUnavailable, CompatibilityAdvanceUnavailable, - compatibility_fidelity_profile, compatibility_projection_from_handler, } import gunbc.native_scm_interaction_contract { @@ -42,13 +41,33 @@ fn synthetic_fourth_handler( advance: CompatibilityAdvanceUnavailable { cause: "synthetic R0 intentionally has no conditional advance", }, - fidelity: compatibility_fidelity_profile( - first: CompatibilityFidelityFact { - axis: CompatibilityEndpointState, - disposition: CompatibilityFidelityPreserved, + fidelity: CompatibilityFidelityProfile { + endpoint_state: CompatibilityFidelityPreserved, + upstream_change_evidence: CompatibilityFidelityUnavailable { + cause: "synthetic fixture carries endpoint state only", }, - remaining: [], - ), + native_proposal_contract: CompatibilityFidelityUnavailable { + cause: "synthetic fixture carries endpoint state only", + }, + history: CompatibilityFidelityUnavailable { + cause: "synthetic fixture carries endpoint state only", + }, + publication: CompatibilityFidelityUnavailable { + cause: "synthetic fixture carries endpoint state only", + }, + conflict_facts: CompatibilityFidelityUnavailable { + cause: "synthetic fixture carries endpoint state only", + }, + path_and_mode: CompatibilityFidelityUnavailable { + cause: "synthetic fixture carries endpoint state only", + }, + availability: CompatibilityFidelityUnavailable { + cause: "synthetic fixture carries endpoint state only", + }, + native_identity: CompatibilityFidelityUnavailable { + cause: "synthetic fixture carries endpoint state only", + }, + }, } }, } diff --git a/docs/plans/dag-scm-design.md b/docs/plans/dag-scm-design.md index 95970eed99b..85786781784 100644 --- a/docs/plans/dag-scm-design.md +++ b/docs/plans/dag-scm-design.md @@ -887,12 +887,13 @@ local locks, or “most recent” state. The semantic kernel consumes native pro states, claims, and receipts; it never consumes a Git commit, Mercurial changeset, or Pijul change as though that upstream object were the semantic contract. -The landed C0 interaction carrier (`gunbc.native_scm_interaction_contract`) is deliberately only a -presentation fixture. Its optional `git` projection and two Git-named scenarios are now a counted -frontier, not the shared adapter interface. They must not be consumed by the proof kernel. Their -dissolution trigger is the three-upstream compatibility-shape slice: replace the fixture slot with -adapter-indexed projection receipts derived from the extracted roles, while keeping the dead-simple -primary outcome byte/behavior stable. +The landed C0 interaction carrier (`gunbc.native_scm_interaction_contract`) remains deliberately +only a presentation fixture. R1 dissolves its former optional `git` slot and Git-named scenario +surface into realization-indexed receipts plus realization-neutral projection/import journeys. +`gunbc.scm_compatibility_shape` owns the extracted presentation/capability roles; the Git, +Mercurial, and Pijul handlers retain their native receipts beside it. Neither carrier may be +consumed as a semantic/admission or Applied receipt, and C0's dead-simple primary outcome behavior +remains unchanged. ## 9. Admission and CI — linear history without serial work @@ -1252,8 +1253,10 @@ does not wait for a native store: zero/one/many/unclosed space, admission, transition, projection, closure certificates, timestamp non-authority, and scenario corpus as `.dag` facts/witnesses. The landed C0 carrier from PR #7334 supplies twelve presentation-journey witnesses, not the - semantic kernel, evidence relation, or compatibility interface; its optional Git projection is - the explicit R1 frontier. + semantic kernel or evidence relation. R1 replaces its optional Git projection with + realization-indexed projection receipts while preserving the C0-owned identity, transition, + and primary outcome; that projection list remains presentation/compatibility state, not an + admission or Applied receipt. **Accept T1:** every scenario produces its internal receipt and three-arm primary outcome, with only `Landed | ChoiceRequired` as semantic handoffs; nearby REDs prevent always-apply/refuse; removing a closure certificate changes `ClosedOne` to `Unclosed`; self-amendment, From 8795a245487386d82a7804b8854ee6f4525f628f Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Wed, 29 Jul 2026 16:16:08 +0000 Subject: [PATCH 06/23] WIP: business --- dag/gunbc/roadmap_authority.dag | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/dag/gunbc/roadmap_authority.dag b/dag/gunbc/roadmap_authority.dag index d82ddac1758..5834bdee3fa 100644 --- a/dag/gunbc/roadmap_authority.dag +++ b/dag/gunbc/roadmap_authority.dag @@ -1365,11 +1365,7 @@ fn active_section_for(focus: RoadmapFocus) -> RoadmapSection { title: "Active deliverables — dependency order", elements: concat( [ -<<<<<<< HEAD - section_prose(content: "The graph has ten lanes: SCM prerequisites · namespace · P-derive · observation · placement · v1 exit (four finish lines: compiler fixed point, interpreter deleted, products v1-free, zero hand-maintained Rust) · shell · roadmap runtime · fleet/hygiene · hermetic toolchain. The three SCM R0 models, the P−1 evidence carrier, and the toolchain pin model are independent roots; compatibility extraction and later SCM/product lanes remain parked. The P-derive receipt feeds the emitter fixed point, so the v1 chain nests under it. Node fields define boundary, first slice, RED control, exclusions, owner, and handback."), -======= - section_prose(content: "The graph has nine lanes: SCM compatibility · namespace · P-derive · observation · placement · v1 exit (four finish lines: compiler fixed point, interpreter deleted, products v1-free, zero hand-maintained Rust) · shell · roadmap runtime · fleet/hygiene. The three independent SCM R0 models and P−1 evidence carrier are landed prerequisites; R1 compatibility-shape extraction is the active SCM slice, while semantic-kernel and later product lanes remain parked. The P-derive receipt feeds the emitter fixed point, so the v1 chain nests under it. Node fields define boundary, first slice, RED control, exclusions, owner, and handback."), ->>>>>>> fa45abd9601 (WIP: business) + section_prose(content: "The graph has ten lanes: SCM compatibility · namespace · P-derive · observation · placement · v1 exit (four finish lines: compiler fixed point, interpreter deleted, products v1-free, zero hand-maintained Rust) · shell · roadmap runtime · fleet/hygiene · hermetic toolchain. The three independent SCM R0 models and P−1 evidence carrier are landed prerequisites; R1 compatibility-shape extraction is the active SCM slice, while semantic-kernel and later product lanes remain parked. The toolchain pin model is an independent root. The P-derive receipt feeds the emitter fixed point, so the v1 chain nests under it. Node fields define boundary, first slice, RED control, exclusions, owner, and handback."), ], concat( if focus_is_active(focus: focus) { From a08225f088139c7cef8cad75c014219662af1985 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Wed, 29 Jul 2026 03:59:55 +0000 Subject: [PATCH 07/23] WIP: business --- dag/gunbc/scm_compatibility_shape.dag | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/dag/gunbc/scm_compatibility_shape.dag b/dag/gunbc/scm_compatibility_shape.dag index 8a2892aa286..4d258433c0a 100644 --- a/dag/gunbc/scm_compatibility_shape.dag +++ b/dag/gunbc/scm_compatibility_shape.dag @@ -14,12 +14,10 @@ type CompatibilityRepairHandle = NonEmptyStr where brand("CompatibilityRepairHan type CompatibilityCaptureClass = CompatibilityEndpointStateCaptured | CompatibilityUpstreamChangeEvidenceCaptured - | CompatibilityNativeProposalCaptured type CompatibilityCaptureClassFold { endpoint_state: fn() -> R upstream_change_evidence: fn() -> R - native_proposal: fn() -> R } fn compatibility_capture_class_fold( @@ -29,7 +27,6 @@ fn compatibility_capture_class_fold( match capture { CompatibilityEndpointStateCaptured => fold.endpoint_state() CompatibilityUpstreamChangeEvidenceCaptured => fold.upstream_change_evidence() - CompatibilityNativeProposalCaptured => fold.native_proposal() } } @@ -69,8 +66,10 @@ type CompatibilityFidelityProfile { type CompatibilityAdvanceGuarantee = CompatibilityExactCompareAndAdvance - | CompatibilitySerializedConditionalAdvance - | CompatibilityUpstreamSpecificConditionalAdvance + | CompatibilityNamedConditionalAdvance { + authority: NonEmptyStr, + contract: NonEmptyStr, + } type CompatibilityAdvanceCapability = CompatibilityAdvanceModeled { From 433d28cca108444e2653e636fa535ca2af8a0eb8 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Wed, 29 Jul 2026 04:01:25 +0000 Subject: [PATCH 08/23] WIP: business --- dag/gunbc/scm_compatibility/git.dag | 275 ++++++++++++++++-- .../scm_compatibility_git_witness_test.dag | 15 +- 2 files changed, 271 insertions(+), 19 deletions(-) diff --git a/dag/gunbc/scm_compatibility/git.dag b/dag/gunbc/scm_compatibility/git.dag index 7d61d7bb9a2..901b12d8915 100644 --- a/dag/gunbc/scm_compatibility/git.dag +++ b/dag/gunbc/scm_compatibility/git.dag @@ -1,23 +1,45 @@ module gunbc.scm_compatibility.git import std.types { List, NonEmptyStr } +import std.integer { NonNegativeInt } +import extdeps.git { ObjectType } import extdeps.git.object_store { GitObjectId, + GitObjectFormat, GitRefName, GitRepositoryState, + GitRepositoryDecodeRefusal, + StoredObject, + StoreObjectFold, + ObjectLookupResult, GitR0Projection, GitR0ReadBackObservation, + GitReadBackMismatchAxis, GitModeledRefTransition, GitR0UnsupportedBoundary, - GitProjectionOutcome, GitProjected, - GitReadBackOutcome, + GitProjectionRefused, GitReadBackVerified, - GitUpdateRefOutcome, + GitReadBackMismatch, GitRefTransitionModeled, + GitRefAdvanceRepositoryInvalid, + GitRefAdvanceStale, + GitRefAdvanceMissing, + GitRefAdvanceDuplicate, + GitRefAdvanceSymbolicCycle, + GitRefAdvanceFormatMismatch, + GitRefAdvanceTargetUnavailable, + GitRefAdvanceTargetKindRefused, + ObjectFound, + ObjectPromisorUnavailable, + ObjectUnexpectedlyMissing, + ObjectCorrupt, + ObjectRepositoryInvalid, + store_object_fold, git_project_repository, git_verify_independent_read_back, git_model_update_ref_exact, + git_lookup_object, git_object_id_content_hash, git_r0_unsupported_boundary, } @@ -44,10 +66,61 @@ type GitCompatibilityReceipt { unsupported: List } +type GitCompatibilityObjectPurpose + = GitCompatibilityGenerationCommit + | GitCompatibilityProjectionTree + | GitCompatibilityAdvanceTarget + type GitCompatibilityRefusal - = GitCompatibilityProjectionRejected { outcome: GitProjectionOutcome } - | GitCompatibilityReadBackRejected { outcome: GitReadBackOutcome } - | GitCompatibilityAdvanceRejected { outcome: GitUpdateRefOutcome } + = GitCompatibilityObjectWrongKind { + purpose: GitCompatibilityObjectPurpose, + stored: StoredObject, + } + | GitCompatibilityObjectPromisorUnavailable { + purpose: GitCompatibilityObjectPurpose, + oid: GitObjectId, + promisor: NonEmptyStr, + } + | GitCompatibilityObjectUnexpectedlyMissing { + purpose: GitCompatibilityObjectPurpose, + oid: GitObjectId, + } + | GitCompatibilityObjectCorrupt { + purpose: GitCompatibilityObjectPurpose, + oid: GitObjectId, + reason: NonEmptyStr, + } + | GitCompatibilityRepositoryInvalid { + purpose: GitCompatibilityObjectPurpose, + cause: GitRepositoryDecodeRefusal, + } + | GitCompatibilityReadBackRejected { axis: GitReadBackMismatchAxis } + | GitCompatibilityAdvanceRepositoryInvalid { + cause: GitRepositoryDecodeRefusal, + } + | GitCompatibilityAdvanceStale { + name: GitRefName, + expected_old: GitObjectId, + observed: GitObjectId, + } + | GitCompatibilityAdvanceMissing { name: GitRefName } + | GitCompatibilityAdvanceDuplicate { + name: GitRefName, + count: NonNegativeInt, + } + | GitCompatibilityAdvanceSymbolicCycle { + name: GitRefName, + chain: List, + } + | GitCompatibilityAdvanceFormatMismatch { + repository_format: GitObjectFormat, + oid: GitObjectId, + } + | GitCompatibilityAdvanceTargetKindRefused { + name: GitRefName, + oid: GitObjectId, + object_type: ObjectType, + } type GitCompatibilityBindingOutcome = GitCompatibilityBound { receipt: GitCompatibilityReceipt } @@ -68,7 +141,42 @@ fn git_compatibility_binding_outcome_fold( } } -fn git_compatibility_bind( +fn git_compatibility_object_refusal( + purpose: GitCompatibilityObjectPurpose, + lookup: ObjectLookupResult, +) -> GitCompatibilityRefusal { + match lookup { + ObjectFound { stored } => + GitCompatibilityObjectWrongKind { + purpose: purpose, + stored: stored, + } + ObjectPromisorUnavailable { oid, promisor } => + GitCompatibilityObjectPromisorUnavailable { + purpose: purpose, + oid: oid, + promisor: promisor, + } + ObjectUnexpectedlyMissing { oid } => + GitCompatibilityObjectUnexpectedlyMissing { + purpose: purpose, + oid: oid, + } + ObjectCorrupt { oid, reason } => + GitCompatibilityObjectCorrupt { + purpose: purpose, + oid: oid, + reason: reason, + } + ObjectRepositoryInvalid { cause } => + GitCompatibilityRepositoryInvalid { + purpose: purpose, + cause: cause, + } + } +} + +fn git_compatibility_bind_commit( repository: GitRepositoryState, tree: GitObjectId, read_back: GitR0ReadBackObservation, @@ -106,25 +214,158 @@ fn git_compatibility_bind( unsupported: git_r0_unsupported_boundary, }, } - rejected => + GitRefAdvanceRepositoryInvalid { + repository: _, + cause, + } => + GitCompatibilityBindingRefused { + cause: GitCompatibilityAdvanceRepositoryInvalid { + cause: cause, + }, + } + GitRefAdvanceStale { + repository: _, + name, + expected_old, + observed, + } => + GitCompatibilityBindingRefused { + cause: GitCompatibilityAdvanceStale { + name: name, + expected_old: expected_old, + observed: observed, + }, + } + GitRefAdvanceMissing { repository: _, name } => + GitCompatibilityBindingRefused { + cause: GitCompatibilityAdvanceMissing { name: name }, + } + GitRefAdvanceDuplicate { + repository: _, + name, + count, + } => + GitCompatibilityBindingRefused { + cause: GitCompatibilityAdvanceDuplicate { + name: name, + count: count, + }, + } + GitRefAdvanceSymbolicCycle { + repository: _, + name, + chain, + } => + GitCompatibilityBindingRefused { + cause: GitCompatibilityAdvanceSymbolicCycle { + name: name, + chain: chain, + }, + } + GitRefAdvanceFormatMismatch { + repository: _, + repository_format, + oid, + } => + GitCompatibilityBindingRefused { + cause: GitCompatibilityAdvanceFormatMismatch { + repository_format: repository_format, + oid: oid, + }, + } + GitRefAdvanceTargetUnavailable { + repository: _, + oid: _, + lookup, + } => + GitCompatibilityBindingRefused { + cause: git_compatibility_object_refusal( + purpose: GitCompatibilityAdvanceTarget, + lookup: lookup, + ), + } + GitRefAdvanceTargetKindRefused { + repository: _, + name, + oid, + object_type, + } => GitCompatibilityBindingRefused { - cause: GitCompatibilityAdvanceRejected { - outcome: rejected, + cause: GitCompatibilityAdvanceTargetKindRefused { + name: name, + oid: oid, + object_type: object_type, }, } } - rejected => + GitReadBackMismatch { axis } => GitCompatibilityBindingRefused { - cause: GitCompatibilityReadBackRejected { - outcome: rejected, - }, + cause: GitCompatibilityReadBackRejected { axis: axis }, } } - rejected => + GitProjectionRefused { cause } => GitCompatibilityBindingRefused { - cause: GitCompatibilityProjectionRejected { - outcome: rejected, + cause: git_compatibility_object_refusal( + purpose: GitCompatibilityProjectionTree, + lookup: cause, + ), + } + } +} + +fn git_compatibility_generation_wrong_kind( + stored: StoredObject, +) -> GitCompatibilityBindingOutcome { + GitCompatibilityBindingRefused { + cause: GitCompatibilityObjectWrongKind { + purpose: GitCompatibilityGenerationCommit, + stored: stored, + }, + } +} + +fn git_compatibility_bind( + repository: GitRepositoryState, + read_back: GitR0ReadBackObservation, + target: GitRefName, + expected_generation: GitObjectId, + proposed_generation: GitObjectId, +) -> GitCompatibilityBindingOutcome { + match git_lookup_object( + repo: repository, + oid: expected_generation, + ) { + ObjectFound { stored } => + store_object_fold( + object: stored.object, + fold: StoreObjectFold { + blob: fn(_) { + git_compatibility_generation_wrong_kind(stored: stored) + }, + tree: fn(_) { + git_compatibility_generation_wrong_kind(stored: stored) + }, + commit: fn(commit) { + git_compatibility_bind_commit( + repository: repository, + tree: commit.tree, + read_back: read_back, + target: target, + expected_generation: expected_generation, + proposed_generation: proposed_generation, + ) + }, + tag: fn(_) { + git_compatibility_generation_wrong_kind(stored: stored) + }, }, + ) + rejected => + GitCompatibilityBindingRefused { + cause: git_compatibility_object_refusal( + purpose: GitCompatibilityGenerationCommit, + lookup: rejected, + ), } } } diff --git a/dag/test/claim/scm_compatibility_git_witness_test.dag b/dag/test/claim/scm_compatibility_git_witness_test.dag index ced38142c1a..82d8e21de1a 100644 --- a/dag/test/claim/scm_compatibility_git_witness_test.dag +++ b/dag/test/claim/scm_compatibility_git_witness_test.dag @@ -44,7 +44,6 @@ data live_tree_disposition: LiveTreeDisposition = SubstrateInputsOnly fn git_fixture_binding() -> GitCompatibilityBindingOutcome { git_compatibility_bind( repository: fixture_repository(), - tree: sha1_root_tree, read_back: fixture_read_back_observation(), target: "refs/heads/main", expected_generation: sha1_parent_commit, @@ -167,7 +166,6 @@ test fn witness_git_readback_mismatch_refuses_binding() -> Bool { } match git_compatibility_bind( repository: fixture_repository(), - tree: sha1_root_tree, read_back: wrong, target: "refs/heads/main", expected_generation: sha1_parent_commit, @@ -177,3 +175,16 @@ test fn witness_git_readback_mismatch_refuses_binding() -> Bool { GitCompatibilityBound { receipt: _ } => false } } + +test fn witness_git_generation_derives_tree_from_commit() -> Bool { + match git_compatibility_bind( + repository: fixture_repository(), + read_back: fixture_read_back_observation(), + target: "refs/heads/main", + expected_generation: sha1_root_tree, + proposed_generation: sha1_next_commit, + ) { + GitCompatibilityBindingRefused { cause: _ } => true + GitCompatibilityBound { receipt: _ } => false + } +} From 483976bb395b543f8a48425d0847c4a6c7b1ba79 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Wed, 29 Jul 2026 04:02:55 +0000 Subject: [PATCH 09/23] WIP: business --- dag/gunbc/scm_compatibility/pijul.dag | 7 +- .../scm_compatibility_shape_witness_test.dag | 71 +++++++++++++++++++ 2 files changed, 75 insertions(+), 3 deletions(-) diff --git a/dag/gunbc/scm_compatibility/pijul.dag b/dag/gunbc/scm_compatibility/pijul.dag index cab686d6d21..5f3105628c8 100644 --- a/dag/gunbc/scm_compatibility/pijul.dag +++ b/dag/gunbc/scm_compatibility/pijul.dag @@ -9,6 +9,7 @@ import extdeps.pijul { PijulDecodedRepository, PijulProjectionRefusal, PijulReadBackObservation, + PijulReadBackMismatchAxis, PijulConditionalAdvanceCapability, PijulDecoded, PijulDecodeRefused, @@ -46,7 +47,7 @@ type PijulCompatibilityReceipt { type PijulCompatibilityRefusal = PijulCompatibilityDecodeRejected { cause: PijulProjectionRefusal } | PijulCompatibilityTargetMissing { target: PijulChannelName } - | PijulCompatibilityReadBackMismatch + | PijulCompatibilityReadBackMismatch { axis: PijulReadBackMismatchAxis } | PijulCompatibilityReadBackInvalid { cause: PijulProjectionRefusal } type PijulCompatibilityBindingOutcome @@ -103,9 +104,9 @@ fn pijul_compatibility_bind( advance: pijul_r0_conditional_advance(), }, } - PijulReadBackMismatch { axis: _ } => + PijulReadBackMismatch { axis } => PijulCompatibilityBindingRefused { - cause: PijulCompatibilityReadBackMismatch, + cause: PijulCompatibilityReadBackMismatch { axis: axis }, } PijulReadBackInvalid { cause } => PijulCompatibilityBindingRefused { diff --git a/dag/test/claim/scm_compatibility_shape_witness_test.dag b/dag/test/claim/scm_compatibility_shape_witness_test.dag index e9d04a20b57..04c7b5a83ce 100644 --- a/dag/test/claim/scm_compatibility_shape_witness_test.dag +++ b/dag/test/claim/scm_compatibility_shape_witness_test.dag @@ -18,6 +18,30 @@ import gunbc.native_scm_interaction_contract { native_scm_primary_label, native_scm_attach_projection, } +import test.claim.scm_compatibility_git_witness { + git_fixture_binding, +} +import test.claim.scm_compatibility_mercurial_witness { + mercurial_fixture_binding, +} +import test.claim.scm_compatibility_pijul_witness { + pijul_fixture_binding, +} +import gunbc.scm_compatibility.git { + GitCompatibilityBound, + GitCompatibilityBindingRefused, + git_compatibility_projection_receipt, +} +import gunbc.scm_compatibility.mercurial { + MercurialCompatibilityBound, + MercurialCompatibilityBindingRefused, + mercurial_compatibility_projection_receipt, +} +import gunbc.scm_compatibility.pijul { + PijulCompatibilityBound, + PijulCompatibilityBindingRefused, + pijul_compatibility_projection_receipt, +} data live_tree_disposition: LiveTreeDisposition = SubstrateInputsOnly @@ -141,3 +165,50 @@ test fn witness_projection_attachment_is_idempotent_per_realization_target() -> ) && count(second_target.projections.realizations) == 2 } + +test fn witness_one_c0_fixture_projects_through_three_native_realizations() -> Bool { + let original = native_scm_receipt_for( + scenario: TwoIndependentChangesLand, + ) + match git_fixture_binding() { + GitCompatibilityBindingRefused { cause: _ } => false + GitCompatibilityBound { receipt: git } => + match mercurial_fixture_binding() { + MercurialCompatibilityBindingRefused { cause: _ } => false + MercurialCompatibilityBound { receipt: mercurial } => + match pijul_fixture_binding() { + PijulCompatibilityBindingRefused { cause: _ } => false + PijulCompatibilityBound { receipt: pijul } => { + let with_git = native_scm_attach_projection( + receipt: original, + projection: git_compatibility_projection_receipt( + receipt: git, + ), + ) + let with_mercurial = native_scm_attach_projection( + receipt: with_git, + projection: mercurial_compatibility_projection_receipt( + receipt: mercurial, + ), + ) + let with_all = native_scm_attach_projection( + receipt: with_mercurial, + projection: pijul_compatibility_projection_receipt( + receipt: pijul, + ), + ) + with_all.identity == original.identity + && with_all.transition == original.transition + && with_all.primary == original.primary + && count(with_all.projections.realizations) == 3 + && with_all.projections.realizations + |> any(row => row.realization == "git-r0") + && with_all.projections.realizations + |> any(row => row.realization == "mercurial-r0") + && with_all.projections.realizations + |> any(row => row.realization == "pijul-r0") + } + } + } + } +} From e1a38268fc18d791816428ad147ed032d5a94d26 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Wed, 29 Jul 2026 04:08:55 +0000 Subject: [PATCH 10/23] WIP: business --- .../scm_compatibility_shape_witness_test.dag | 124 ++++++++---------- 1 file changed, 57 insertions(+), 67 deletions(-) diff --git a/dag/test/claim/scm_compatibility_shape_witness_test.dag b/dag/test/claim/scm_compatibility_shape_witness_test.dag index 04c7b5a83ce..bac2b0d24f5 100644 --- a/dag/test/claim/scm_compatibility_shape_witness_test.dag +++ b/dag/test/claim/scm_compatibility_shape_witness_test.dag @@ -18,31 +18,6 @@ import gunbc.native_scm_interaction_contract { native_scm_primary_label, native_scm_attach_projection, } -import test.claim.scm_compatibility_git_witness { - git_fixture_binding, -} -import test.claim.scm_compatibility_mercurial_witness { - mercurial_fixture_binding, -} -import test.claim.scm_compatibility_pijul_witness { - pijul_fixture_binding, -} -import gunbc.scm_compatibility.git { - GitCompatibilityBound, - GitCompatibilityBindingRefused, - git_compatibility_projection_receipt, -} -import gunbc.scm_compatibility.mercurial { - MercurialCompatibilityBound, - MercurialCompatibilityBindingRefused, - mercurial_compatibility_projection_receipt, -} -import gunbc.scm_compatibility.pijul { - PijulCompatibilityBound, - PijulCompatibilityBindingRefused, - pijul_compatibility_projection_receipt, -} - data live_tree_disposition: LiveTreeDisposition = SubstrateInputsOnly type SyntheticFourthReceipt { @@ -110,6 +85,28 @@ fn synthetic_projection( ) } +fn named_fixture_projection( + realization: NonEmptyStr, + target: NonEmptyStr, + generation: NonEmptyStr, +) -> CompatibilityProjectionReceipt { + let synthetic = synthetic_projection( + target: target, + generation: generation, + ) + CompatibilityProjectionReceipt { + realization: realization, + target: synthetic.target, + generation_evidence: synthetic.generation_evidence, + capture: synthetic.capture, + projection: synthetic.projection, + read_back: synthetic.read_back, + repair: synthetic.repair, + advance: synthetic.advance, + fidelity: synthetic.fidelity, + } +} + test fn witness_fourth_realization_adds_handler_without_primary_edit() -> Bool { let original = native_scm_receipt_for( scenario: TwoIndependentChangesLand, @@ -166,49 +163,42 @@ test fn witness_projection_attachment_is_idempotent_per_realization_target() -> && count(second_target.projections.realizations) == 2 } -test fn witness_one_c0_fixture_projects_through_three_native_realizations() -> Bool { +test fn witness_one_c0_fixture_accepts_three_realization_receipts() -> Bool { let original = native_scm_receipt_for( scenario: TwoIndependentChangesLand, ) - match git_fixture_binding() { - GitCompatibilityBindingRefused { cause: _ } => false - GitCompatibilityBound { receipt: git } => - match mercurial_fixture_binding() { - MercurialCompatibilityBindingRefused { cause: _ } => false - MercurialCompatibilityBound { receipt: mercurial } => - match pijul_fixture_binding() { - PijulCompatibilityBindingRefused { cause: _ } => false - PijulCompatibilityBound { receipt: pijul } => { - let with_git = native_scm_attach_projection( - receipt: original, - projection: git_compatibility_projection_receipt( - receipt: git, - ), - ) - let with_mercurial = native_scm_attach_projection( - receipt: with_git, - projection: mercurial_compatibility_projection_receipt( - receipt: mercurial, - ), - ) - let with_all = native_scm_attach_projection( - receipt: with_mercurial, - projection: pijul_compatibility_projection_receipt( - receipt: pijul, - ), - ) - with_all.identity == original.identity - && with_all.transition == original.transition - && with_all.primary == original.primary - && count(with_all.projections.realizations) == 3 - && with_all.projections.realizations - |> any(row => row.realization == "git-r0") - && with_all.projections.realizations - |> any(row => row.realization == "mercurial-r0") - && with_all.projections.realizations - |> any(row => row.realization == "pijul-r0") - } - } - } - } + let with_git = native_scm_attach_projection( + receipt: original, + projection: named_fixture_projection( + realization: "git-r0", + target: "refs/heads/main", + generation: "git-generation", + ), + ) + let with_mercurial = native_scm_attach_projection( + receipt: with_git, + projection: named_fixture_projection( + realization: "mercurial-r0", + target: "default", + generation: "mercurial-generation", + ), + ) + let with_all = native_scm_attach_projection( + receipt: with_mercurial, + projection: named_fixture_projection( + realization: "pijul-r0", + target: "main", + generation: "pijul-generation", + ), + ) + with_all.identity == original.identity + && with_all.transition == original.transition + && with_all.primary == original.primary + && count(with_all.projections.realizations) == 3 + && with_all.projections.realizations + |> any(row => row.realization == "git-r0") + && with_all.projections.realizations + |> any(row => row.realization == "mercurial-r0") + && with_all.projections.realizations + |> any(row => row.realization == "pijul-r0") } From b41890c82eabe59e8c554a0cae7bc31259733bd9 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Wed, 29 Jul 2026 04:31:27 +0000 Subject: [PATCH 11/23] WIP: business --- dag/gunbc/native_scm_interaction_contract.dag | 2 +- dag/gunbc/roadmap_authority.dag | 8 +-- dag/gunbc/scm_compatibility/git.dag | 1 - dag/gunbc/scm_compatibility/mercurial.dag | 1 - dag/gunbc/scm_compatibility/pijul.dag | 1 - dag/gunbc/scm_compatibility_shape.dag | 67 +------------------ ..._scm_interaction_contract_witness_test.dag | 5 +- .../scm_compatibility_git_witness_test.dag | 11 +-- .../scm_compatibility_shape_witness_test.dag | 2 - docs/plans/dag-scm-design.md | 11 ++- 10 files changed, 24 insertions(+), 85 deletions(-) diff --git a/dag/gunbc/native_scm_interaction_contract.dag b/dag/gunbc/native_scm_interaction_contract.dag index 919e9e656d0..7ed83457d92 100644 --- a/dag/gunbc/native_scm_interaction_contract.dag +++ b/dag/gunbc/native_scm_interaction_contract.dag @@ -476,7 +476,7 @@ fn native_scm_attach_projection( } } -fn native_scm_repair_projection( +fn native_scm_record_repaired_projection( receipt: NativeScmReceipt, projection: CompatibilityProjectionReceipt, ) -> NativeScmReceipt { diff --git a/dag/gunbc/roadmap_authority.dag b/dag/gunbc/roadmap_authority.dag index 5834bdee3fa..7e96431a7ae 100644 --- a/dag/gunbc/roadmap_authority.dag +++ b/dag/gunbc/roadmap_authority.dag @@ -376,12 +376,12 @@ fn declared_roadmap_nodes() -> List { volume: VolumeMedium, t: fields( headline: "Extract the compatibility realization shape from three upstream receipts", - boundary: "Consume the independently executing Git, Mercurial, and Pijul R0 boundaries and extract only their demonstrated roles: opaque target/generation handles, capture class, fidelity profile, projection/read-back/repair identity, and explicit conditional-advance capability. Native receipts retain every upstream-specific fact; dispatch is a generic handler value, never ScmKind or a vendor switch.", + boundary: "Consume the independently executing Git, Mercurial, and Pijul R0 boundaries and extract only their demonstrated roles: opaque target/generation handles, capture class, fidelity profile, projection/read-back identity, and modeled-or-unavailable conditional-advance capability. Native receipts retain every upstream-specific fact; dispatch is a generic handler value, never ScmKind or a vendor switch.", displaced_cost: "Lets the native edit → submit → outcome contract project through plural SCMs without forcing users into Git mechanics or erasing Mercurial/Pijul distinctions into a first-adapter abstraction.", first_slice: "Bind each R0 fixture through its native decoder and read-back assessment, replace C0's optional Git projection slot with realization-indexed receipts, and execute one fixed C0 proposal through Git, Mercurial, Pijul, and a synthetic fourth handler.", - red_control: "C0 proposal identity, transition, and primary outcome stay unchanged across all realizations; missing required conditional advance refuses; modeled Git advance cannot satisfy executed advance; a read-back mismatch refuses; the fourth handler requires no primary-contract or kernel edit.", - out_of_scope: "No semantic candidate space, admission policy, Applied receipt, universal commit/ref/channel type, hosted service, writable Mercurial/Pijul target, or central realization enum.", - handback: "Return the shared role carrier, three native adapter receipts, fidelity/capability matrix, realization-indexed C0 projection, idempotent repair receipt, and the exact distinctions deliberately left native." + red_control: "C0 proposal identity, transition, and primary outcome stay unchanged across all realizations; missing or differently grounded conditional advance refuses; a read-back mismatch refuses; the fourth handler requires no primary-contract or kernel edit.", + out_of_scope: "No semantic candidate space, admission policy, repair capability, executed transition, Applied receipt, universal commit/ref/channel type, hosted service, writable Mercurial/Pijul target, or central realization enum.", + handback: "Return the shared role carrier, three native adapter receipts, fidelity/capability matrix, realization-indexed C0 projection with idempotent replacement identity, and the exact distinctions deliberately left native." ) ), diff --git a/dag/gunbc/scm_compatibility/git.dag b/dag/gunbc/scm_compatibility/git.dag index 901b12d8915..92c7862ce53 100644 --- a/dag/gunbc/scm_compatibility/git.dag +++ b/dag/gunbc/scm_compatibility/git.dag @@ -404,7 +404,6 @@ fn git_compatibility_projection_receipt( capture: CompatibilityEndpointStateCaptured, projection: projection, read_back: concat("git-readback:", receipt.read_back.git_version), - repair: concat("git-projection-repair:", projection), advance: CompatibilityAdvanceModeled { guarantee: CompatibilityExactCompareAndAdvance, }, diff --git a/dag/gunbc/scm_compatibility/mercurial.dag b/dag/gunbc/scm_compatibility/mercurial.dag index ae28bf83ec5..6dcec642bc2 100644 --- a/dag/gunbc/scm_compatibility/mercurial.dag +++ b/dag/gunbc/scm_compatibility/mercurial.dag @@ -209,7 +209,6 @@ fn mercurial_compatibility_projection_receipt( "mercurial-readback:", receipt.read_back.observed_by, ), - repair: concat("mercurial-projection-repair:", generation), advance: CompatibilityAdvanceUnavailable { cause: reason }, fidelity: mercurial_compatibility_fidelity(), } diff --git a/dag/gunbc/scm_compatibility/pijul.dag b/dag/gunbc/scm_compatibility/pijul.dag index 5f3105628c8..068971783c9 100644 --- a/dag/gunbc/scm_compatibility/pijul.dag +++ b/dag/gunbc/scm_compatibility/pijul.dag @@ -148,7 +148,6 @@ fn pijul_compatibility_projection_receipt( capture: CompatibilityUpstreamChangeEvidenceCaptured, projection: concat("pijul-channel-state:", generation), read_back: concat("pijul-readback:", generation), - repair: concat("pijul-projection-repair:", generation), advance: CompatibilityAdvanceUnavailable { cause: reason }, fidelity: pijul_compatibility_fidelity(), } diff --git a/dag/gunbc/scm_compatibility_shape.dag b/dag/gunbc/scm_compatibility_shape.dag index 4d258433c0a..f7f8fd001f6 100644 --- a/dag/gunbc/scm_compatibility_shape.dag +++ b/dag/gunbc/scm_compatibility_shape.dag @@ -2,14 +2,13 @@ module gunbc.scm_compatibility_shape import std.types { Bool, List, NonEmptyStr } -data scm_compatibility_shape_note: NonEmptyStr = "R1 compatibility-realization shape extracted from the independently executing Git, Mercurial, and Pijul R0 boundaries. The shared carrier owns only roles demonstrated by all three: an opaque realization and target handle, a handle to native generation evidence, honest capture fidelity, realization-specific preservation/loss facts, projection plus independent read-back, idempotent repair identity, and an explicit conditional-advance capability. Native evidence remains in adapter-specific typed receipts; this presentation projection is not a semantic, policy, commit, or Applied receipt. Dispatch is a generic handler value, never ScmKind or a vendor switch. A fourth realization supplies one handler and does not edit this module or the native interaction contract." +data scm_compatibility_shape_note: NonEmptyStr = "R1 compatibility-realization shape extracted from the independently executing Git, Mercurial, and Pijul R0 boundaries. The shared carrier owns only roles demonstrated by the landed R0s: an opaque realization and target handle, a handle to native generation evidence, honest capture fidelity, realization-specific preservation/loss facts, projection plus independent read-back, and an explicit modeled-or-unavailable conditional-advance capability. Native evidence remains in adapter-specific typed receipts; this presentation projection is not a semantic, policy, repair, execution, commit, or Applied receipt. A failed projection may later be replaced idempotently by realization and target only after some external operation supplies a new independently read-back receipt. Dispatch is a generic handler value, never ScmKind or a vendor switch. A fourth realization supplies one handler and does not edit this module or the native interaction contract." type CompatibilityRealizationHandle = NonEmptyStr where brand("CompatibilityRealizationHandle") type CompatibilityTargetHandle = NonEmptyStr where brand("CompatibilityTargetHandle") type CompatibilityGenerationEvidenceHandle = NonEmptyStr where brand("CompatibilityGenerationEvidenceHandle") type CompatibilityProjectionHandle = NonEmptyStr where brand("CompatibilityProjectionHandle") type CompatibilityReadBackHandle = NonEmptyStr where brand("CompatibilityReadBackHandle") -type CompatibilityRepairHandle = NonEmptyStr where brand("CompatibilityRepairHandle") type CompatibilityCaptureClass = CompatibilityEndpointStateCaptured @@ -75,14 +74,10 @@ type CompatibilityAdvanceCapability = CompatibilityAdvanceModeled { guarantee: CompatibilityAdvanceGuarantee, } - | CompatibilityAdvanceExecutedAndReadBack { - guarantee: CompatibilityAdvanceGuarantee, - } | CompatibilityAdvanceUnavailable { cause: NonEmptyStr } type CompatibilityAdvanceCapabilityFold { modeled: fn(CompatibilityAdvanceGuarantee) -> R - executed_and_read_back: fn(CompatibilityAdvanceGuarantee) -> R unavailable: fn(NonEmptyStr) -> R } @@ -92,8 +87,6 @@ fn compatibility_advance_capability_fold( ) -> R { match capability { CompatibilityAdvanceModeled { guarantee } => fold.modeled(guarantee) - CompatibilityAdvanceExecutedAndReadBack { guarantee } => - fold.executed_and_read_back(guarantee) CompatibilityAdvanceUnavailable { cause } => fold.unavailable(cause) } } @@ -103,14 +96,10 @@ type CompatibilityAdvanceRequirement | CompatibilityModeledAdvanceRequired { guarantee: CompatibilityAdvanceGuarantee, } - | CompatibilityExecutedAdvanceRequired { - guarantee: CompatibilityAdvanceGuarantee, - } type CompatibilityAdvanceRequirementFold { observation_only: fn() -> R modeled_required: fn(CompatibilityAdvanceGuarantee) -> R - executed_required: fn(CompatibilityAdvanceGuarantee) -> R } fn compatibility_advance_requirement_fold( @@ -121,8 +110,6 @@ fn compatibility_advance_requirement_fold( CompatibilityObservationOnly => fold.observation_only() CompatibilityModeledAdvanceRequired { guarantee } => fold.modeled_required(guarantee) - CompatibilityExecutedAdvanceRequired { guarantee } => - fold.executed_required(guarantee) } } @@ -167,50 +154,6 @@ fn compatibility_modeled_requirement_check( } } }, - executed_and_read_back: fn(actual) { - if actual == required { - CompatibilityCapabilitySatisfied - } else { - CompatibilityCapabilityRefused { - requirement: original, - observed: observed, - } - } - }, - unavailable: fn(_) { - CompatibilityCapabilityRefused { - requirement: original, - observed: observed, - } - }, - }, - ) -} - -fn compatibility_executed_requirement_check( - required: CompatibilityAdvanceGuarantee, - observed: CompatibilityAdvanceCapability, - original: CompatibilityAdvanceRequirement, -) -> CompatibilityCapabilityCheck { - compatibility_advance_capability_fold( - capability: observed, - fold: CompatibilityAdvanceCapabilityFold { - modeled: fn(_) { - CompatibilityCapabilityRefused { - requirement: original, - observed: observed, - } - }, - executed_and_read_back: fn(actual) { - if actual == required { - CompatibilityCapabilitySatisfied - } else { - CompatibilityCapabilityRefused { - requirement: original, - observed: observed, - } - } - }, unavailable: fn(_) { CompatibilityCapabilityRefused { requirement: original, @@ -238,13 +181,6 @@ fn compatibility_check_advance_requirement( original: requirement, ) }, - executed_required: fn(required) { - compatibility_executed_requirement_check( - required: required, - observed: observed, - original: requirement, - ) - }, }, ) } @@ -256,7 +192,6 @@ type CompatibilityProjectionReceipt { capture: CompatibilityCaptureClass projection: CompatibilityProjectionHandle read_back: CompatibilityReadBackHandle - repair: CompatibilityRepairHandle advance: CompatibilityAdvanceCapability fidelity: CompatibilityFidelityProfile } diff --git a/dag/test/claim/native_scm_interaction_contract_witness_test.dag b/dag/test/claim/native_scm_interaction_contract_witness_test.dag index 330f54ae438..8749f9d95ef 100644 --- a/dag/test/claim/native_scm_interaction_contract_witness_test.dag +++ b/dag/test/claim/native_scm_interaction_contract_witness_test.dag @@ -20,7 +20,7 @@ import gunbc.native_scm_interaction_contract { native_scm_receipt_for, native_scm_primary_label, native_scm_resolve_choice, - native_scm_repair_projection, + native_scm_record_repaired_projection, native_scm_inspect_receipt, native_scm_submission_ledger, native_scm_apply_once, @@ -54,7 +54,6 @@ fn fixture_compatibility_projection() -> CompatibilityProjectionReceipt { capture: CompatibilityEndpointStateCaptured, projection: "git-projection-fixture", read_back: "git-readback-fixture", - repair: "git-repair-fixture", advance: CompatibilityAdvanceUnavailable { cause: "C0 witness does not establish an executing transition", }, @@ -206,7 +205,7 @@ test fn witness_tool_model_proof_deficits_stay_internal() -> Bool { test fn witness_projection_failure_repairs_without_reinterpretation() -> Bool { let r = receipt_for(scenario: ProjectionFailureRepairsWithoutReinterpretation) - let repaired = native_scm_repair_projection( + let repaired = native_scm_record_repaired_projection( receipt: r, projection: fixture_compatibility_projection(), ) diff --git a/dag/test/claim/scm_compatibility_git_witness_test.dag b/dag/test/claim/scm_compatibility_git_witness_test.dag index 82d8e21de1a..a1b728acdf2 100644 --- a/dag/test/claim/scm_compatibility_git_witness_test.dag +++ b/dag/test/claim/scm_compatibility_git_witness_test.dag @@ -24,9 +24,9 @@ import gunbc.scm_compatibility_shape { CompatibilityFidelityDowngraded, CompatibilityAdvanceModeled, CompatibilityExactCompareAndAdvance, + CompatibilityNamedConditionalAdvance, CompatibilityObservationOnly, CompatibilityModeledAdvanceRequired, - CompatibilityExecutedAdvanceRequired, CompatibilityCapabilitySatisfied, CompatibilityCapabilityRefused, compatibility_projection_from_handler, @@ -91,7 +91,7 @@ test fn witness_git_realization_preserves_c0_primary_behavior() -> Bool { } } -test fn witness_git_modeled_advance_is_not_executed_advance() -> Bool { +test fn witness_git_modeled_advance_refuses_different_guarantee() -> Bool { match git_fixture_binding() { GitCompatibilityBindingRefused { cause: _ } => false GitCompatibilityBound { receipt } => { @@ -111,8 +111,11 @@ test fn witness_git_modeled_advance_is_not_executed_advance() -> Bool { ) { CompatibilityCapabilitySatisfied => match compatibility_check_advance_requirement( - requirement: CompatibilityExecutedAdvanceRequired { - guarantee: CompatibilityExactCompareAndAdvance, + requirement: CompatibilityModeledAdvanceRequired { + guarantee: CompatibilityNamedConditionalAdvance { + authority: "fixture-other-authority", + contract: "fixture-other-contract", + }, }, observed: capability, ) { diff --git a/dag/test/claim/scm_compatibility_shape_witness_test.dag b/dag/test/claim/scm_compatibility_shape_witness_test.dag index bac2b0d24f5..f24e5a1372f 100644 --- a/dag/test/claim/scm_compatibility_shape_witness_test.dag +++ b/dag/test/claim/scm_compatibility_shape_witness_test.dag @@ -36,7 +36,6 @@ fn synthetic_fourth_handler( capture: CompatibilityEndpointStateCaptured, projection: concat("synthetic-projection:", receipt.generation), read_back: concat("synthetic-readback:", receipt.generation), - repair: concat("synthetic-repair:", receipt.generation), advance: CompatibilityAdvanceUnavailable { cause: "synthetic R0 intentionally has no conditional advance", }, @@ -101,7 +100,6 @@ fn named_fixture_projection( capture: synthetic.capture, projection: synthetic.projection, read_back: synthetic.read_back, - repair: synthetic.repair, advance: synthetic.advance, fidelity: synthetic.fidelity, } diff --git a/docs/plans/dag-scm-design.md b/docs/plans/dag-scm-design.md index 85786781784..93e23e62081 100644 --- a/docs/plans/dag-scm-design.md +++ b/docs/plans/dag-scm-design.md @@ -877,7 +877,9 @@ The shared compatibility boundary is expected to need these **roles**, pending t grounded serialized/transactional guarantee, or capability unavailable/unknown; - project the accepted program and allowed metadata into the upstream representation; - independently read back the projected/advanced state; -- repair an idempotent projection without replaying the semantic transition; and +- replace a projection receipt idempotently by realization and target after an external retry has + produced a new independently read-back receipt; R1 does not model that retry as a repair + capability; and - preserve or explicitly downgrade upstream-specific history, publication, conflict, path/mode, opaque-content, partial-availability, and identity facts. @@ -887,6 +889,10 @@ local locks, or “most recent” state. The semantic kernel consumes native pro states, claims, and receipts; it never consumes a Git commit, Mercurial changeset, or Pijul change as though that upstream object were the semantic contract. +The R1 advance carrier is deliberately only `Modeled | Unavailable`, because none of the three R0 +models executes and independently reads back a target advance. Executed advance and repair +capabilities may be introduced only by the later realization that actually produces those receipts. + The landed C0 interaction carrier (`gunbc.native_scm_interaction_contract`) remains deliberately only a presentation fixture. R1 dissolves its former optional `git` slot and Git-named scenario surface into realization-indexed receipts plus realization-neutral projection/import journeys. @@ -1244,7 +1250,8 @@ does not wait for a native store: required conditional-advance capability refuses that target policy; a synthetic fourth adapter requires no primary-interaction edit. This slice replaces C0's optional `git` fixture slot and Git-named presentation cases with realization-indexed projection receipts without changing - primary behavior. + primary behavior. It does not predeclare an executed-advance or repair-capability state; those + wait for an executing realization. R0 and P−1 may proceed in parallel because neither is allowed to infer the other. R1 waits for all three R0 models; the proof kernel waits for P−1. 5. **P0 — user contract, cost, and layered scenario model:** carry the §0 From 69898b2e1ed1145b95cde8ba9a8d13976e260392 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Wed, 29 Jul 2026 05:07:31 +0000 Subject: [PATCH 12/23] WIP: business --- dag/gunbc/roadmap_authority.dag | 69 ++++++++++++++++++++++++ dag/test/manual/roadmap_digest_probe.dag | 17 ++++++ 2 files changed, 86 insertions(+) create mode 100644 dag/test/manual/roadmap_digest_probe.dag diff --git a/dag/gunbc/roadmap_authority.dag b/dag/gunbc/roadmap_authority.dag index 7e96431a7ae..d702c3f6245 100644 --- a/dag/gunbc/roadmap_authority.dag +++ b/dag/gunbc/roadmap_authority.dag @@ -368,6 +368,70 @@ fn caret_parse_smoke_seed_growth_fields(j: SeedGrowthJustification) -> TicketFie fn declared_roadmap_nodes() -> List { [ + active_sized( + id: "2-scm-git-upstream-model", + owner: "source-intent", + path: "docs/plans/dag-scm-design.md", + intricacy: IntricacyHigh, + volume: VolumeMedium, + t: fields( + headline: "Write down how Git really stores things", + boundary: "Describe Git on its own terms: files, folders, commits, tags, file permissions, symlinks, links to other repositories, and how it names and finds them. Prove it by reading a small repository and writing it back unchanged.", + displaced_cost: "If we invent a one-size-fits-all model first, it quietly drops things like executable permissions and symlinks — and every tool built on top inherits the loss.", + first_slice: "Finish the storage description, then read one small repository and write it back unchanged.", + red_control: "A plain file, an executable file, a symlink, a link to another repository, and a tag all stay distinguishable; writing against an out-of-date starting point refuses instead of overwriting; a missing object never reads as empty.", + out_of_scope: "No shared source-control interface, no hosting or server work, and no guessing that a renamed file is the same file.", + handback: "The model with citations to Git's own docs, the read/write-back receipts, the refusal receipt, and a list of anything we still cannot represent." + ) + ), + active_sized( + id: "2-scm-mercurial-upstream-model", + owner: "source-intent", + path: "docs/plans/dag-scm-design.md", + intricacy: IntricacyHigh, + volume: VolumeMedium, + t: fields( + headline: "Write down how Mercurial really works, in its own words", + boundary: "Describe Mercurial from its own documentation: its permanent change IDs versus the numbers local to one copy, its branches, bookmarks, tags, and its draft/published states. Use no Git vocabulary.", + displaced_cost: "Mercurial's ideas are not Git's. Renaming them into Git words loses the differences, and a later shared design would be built on a mistranslation.", + first_slice: "Write the description and read one small repository back out, leaving anything we cannot safely write marked unavailable.", + red_control: "A copy-local revision number can change while the permanent change ID does not; draft, published, and hidden stay three different things; a bookmark, a named branch, and a branch tip cannot collapse into one idea.", + out_of_scope: "No Mercurial support in the product, no shared source-control interface, and no faking missing facts from timestamps.", + handback: "The description with citations, the read-back receipt, an explicit list of what we cannot do yet, and the differences that must survive into any later shared design." + ) + ), + active_sized( + id: "2-scm-pijul-upstream-model", + owner: "source-intent", + path: "docs/plans/dag-scm-design.md", + intricacy: IntricacyHigh, + volume: VolumeMedium, + t: fields( + headline: "Write down how Pijul really works, in its own words", + boundary: "Describe Pijul from its own documentation: individual changes that carry their own identity, what each change depends on, and how a channel is a set of changes rather than a pointer to the newest one.", + displaced_cost: "Pijul does not have a 'latest commit'. Modelling it as if it does erases the thing that makes it different, and a third viewpoint is what stops us from mistaking Git's habits for universal truth.", + first_slice: "Write the description, then apply a small set of changes, read them back, and try them in a different order.", + red_control: "A channel cannot be reduced to one newest commit; one change keeps the same identity in two channels; applying a change whose prerequisites are missing refuses instead of applying an empty change.", + out_of_scope: "No Pijul support in the product, no adopting its conflict rules as ours, and no shared source-control interface.", + handback: "The description with citations, the round-trip and out-of-order receipts, and an explicit list of what we cannot do yet." + ) + ), + active_sized( + id: "2-claim-indexed-evidence", + owner: "deduction", + path: "docs/plans/dag-scm-design.md", + intricacy: IntricacyHigh, + volume: VolumeMedium, + t: fields( + headline: "Say once what counts as evidence for a claim", + boundary: "One shared way to record a fact, state a claim, and link evidence that supports or contradicts it — including how much a piece of evidence can prove on its own. Three existing features adopt it.", + displaced_cost: "Right now each feature invents its own yes/no test, so a weak signal gets promoted into a confident claim. 'We stored a login' starts meaning 'the login works'.", + first_slice: "Reuse what already exists for this, then run it through the three features that need it and check they agree.", + red_control: "A stored login plus a failed live request supports 'we have a credential' but not 'the service is ready'; contradictory evidence stays contradictory and missing evidence stays missing, rather than the newest answer winning.", + out_of_scope: "No source-control solver, no per-feature copy of the idea, and no treating 'we recorded this' as proof that it is true.", + handback: "The shared model, receipts from all three features, the supports/contradicts/both/neither cases, and anything the substrate still cannot express." + ) + ), active_sized( id: "2-scm-compatibility-shape", owner: "source-intent", @@ -1196,6 +1260,11 @@ fn declared_roadmap_nodes() -> List { fn declared_roadmap_edges() -> List { [ + edge(child: "2-scm-compatibility-shape", parent: "2-scm-git-upstream-model"), + edge(child: "2-scm-compatibility-shape", parent: "2-scm-mercurial-upstream-model"), + edge(child: "2-scm-compatibility-shape", parent: "2-scm-pijul-upstream-model"), + edge(child: "2-scm-compatibility-shape", parent: "2-claim-indexed-evidence"), + edge(child: "namespace-canonical-binding", parent: "namespace-occurrence-transport"), edge(child: "namespace-bound-only-consumers", parent: "namespace-canonical-binding"), edge(child: "namespace-v2-import-completion", parent: "namespace-bound-only-consumers"), diff --git a/dag/test/manual/roadmap_digest_probe.dag b/dag/test/manual/roadmap_digest_probe.dag new file mode 100644 index 00000000000..5895ca52ccc --- /dev/null +++ b/dag/test/manual/roadmap_digest_probe.dag @@ -0,0 +1,17 @@ +module test.manual.roadmap_digest_probe + +import std.types { String } +import v2.std.optional { Present, Absent } +import gunbc.roadmap_authority { declared_roadmap_nodes } +import gunbc.roadmap_model { node_criteria_digest } + +fn main(id: String) -> String { + match declared_roadmap_nodes() |> filter(node => node.node == id) |> first { + Present { value: node } => + match node_criteria_digest(rn: node) { + Present { value: digest } => digest as String + Absent => "criteria-missing" + } + Absent => "node-missing" + } +} From 7f02cc5c67be39f932b5f8783e000036fd7264f1 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Wed, 29 Jul 2026 05:18:03 +0000 Subject: [PATCH 13/23] WIP: business --- dag/gunbc/roadmap_authority.dag | 76 ++++++++++++++++++++ dag/test/claim/roadmap_authority_test.dag | 36 ++++++++-- dag/test/claim/roadmap_page_witness_test.dag | 2 +- dag/test/manual/roadmap_digest_probe.dag | 17 ----- 4 files changed, 107 insertions(+), 24 deletions(-) delete mode 100644 dag/test/manual/roadmap_digest_probe.dag diff --git a/dag/gunbc/roadmap_authority.dag b/dag/gunbc/roadmap_authority.dag index d702c3f6245..493be55e8ff 100644 --- a/dag/gunbc/roadmap_authority.dag +++ b/dag/gunbc/roadmap_authority.dag @@ -1336,10 +1336,86 @@ fn declared_roadmap_edges() -> List { data criteria_digest_reword_note: String = "Both digests below moved on 2026-07-29 because every row was rewritten in plain language, and the digest covers the brief, the pass/fail test, and what gets handed back. Worth being blunt about the limit this exposes: the digest cannot tell a rewording from a genuine change to the bar — it only knows the words moved. Nothing about what these two rows had to prove changed, and the evidence each names is the same run and the same files as before, so re-pinning is correct here. But that judgement was a person's, not the mechanism's, and a reviewer should treat any digest change as a prompt to re-read the row rather than as a formality. This is the same gap roadmap_acceptance_receipt_note already names: until a row's pass/fail test points at the test that discharges it, the link between words and evidence is asserted rather than derived." +data scm_prerequisite_acceptance_note: String = "The operator explicitly advanced the source-intent lane to R1 after merging the Git, Mercurial, Pijul, and claim-indexed-evidence slices. These receipts preserve those four declared prerequisite facts and their executed handbacks; R1 depends on all four in declared_roadmap_edges. Replacing the rows with R1 would erase accepted history and violate roadmap_acceptance_receipt_note." + fn chash(s: String) -> ContentHash { s } fn roadmap_acceptance_receipts() -> List { [ + RoadmapAcceptanceReceipt { + node: nid(s: "2-scm-git-upstream-model"), + criteria_digest: chash(s: "b3747b95baf099cc"), + red_control: RedControlExecuted { + witness_module: "test.manual.git_upstream_model_execution", + witness_fn: "witness_git_cli_fixture_hashes_projects_and_independently_reads_back", + executed_on: "2026-07-29", + }, + handback: HandbackDelivered { + first_artifact: "dag/extdeps/git/object_store.dag", + further_artifacts: [ + "dag/test/claim/git_upstream_model_witness_test.dag", + "dag/test/manual/git_upstream_model_execution_test.dag", + ], + }, + accepted_by: "operator", + accepted_on: "2026-07-29", + }, + RoadmapAcceptanceReceipt { + node: nid(s: "2-scm-mercurial-upstream-model"), + criteria_digest: chash(s: "c43b17d5134b111d"), + red_control: RedControlExecuted { + witness_module: "test.manual.mercurial_upstream_model_execution", + witness_fn: "witness_mercurial_cli_fixture_projects_and_independently_reads_back", + executed_on: "2026-07-29", + }, + handback: HandbackDelivered { + first_artifact: "dag/extdeps/mercurial.dag", + further_artifacts: [ + "dag/test/claim/mercurial_upstream_model_witness_test.dag", + "dag/test/manual/mercurial_upstream_model_execution_test.dag", + ], + }, + accepted_by: "operator", + accepted_on: "2026-07-29", + }, + RoadmapAcceptanceReceipt { + node: nid(s: "2-scm-pijul-upstream-model"), + criteria_digest: chash(s: "098c989bdc87dac7"), + red_control: RedControlExecuted { + witness_module: "test.manual.pijul_upstream_model_execution", + witness_fn: "witness_pijul_cli_fixture_reads_channel_sets_and_retained_conflict", + executed_on: "2026-07-29", + }, + handback: HandbackDelivered { + first_artifact: "dag/extdeps/pijul.dag", + further_artifacts: [ + "dag/test/claim/pijul_upstream_model_witness_test.dag", + "dag/test/manual/pijul_upstream_model_execution_test.dag", + ], + }, + accepted_by: "operator", + accepted_on: "2026-07-29", + }, + RoadmapAcceptanceReceipt { + node: nid(s: "2-claim-indexed-evidence"), + criteria_digest: chash(s: "2b81ac6aacf6a190"), + red_control: RedControlExecuted { + witness_module: "test.claim.claim_indexed_evidence_witness", + witness_fn: "witness_claim_evidence_roles_are_externally_grounded", + executed_on: "2026-07-29", + }, + handback: HandbackDelivered { + first_artifact: "dag/std/claim_evidence.dag", + further_artifacts: [ + "dag/gunbc/provider_readiness_claim_evidence.dag", + "dag/gunbc/os_install_claim_evidence.dag", + "dag/gunbc/source_integration_claim_evidence.dag", + "dag/test/claim/claim_indexed_evidence_witness_test.dag", + ], + }, + accepted_by: "operator", + accepted_on: "2026-07-29", + }, RoadmapAcceptanceReceipt { node: nid(s: "namespace-occurrence-transport"), criteria_digest: chash(s: "d76cf14b12dbf4bf"), diff --git a/dag/test/claim/roadmap_authority_test.dag b/dag/test/claim/roadmap_authority_test.dag index 92c80ffea21..2fbb32d92e8 100644 --- a/dag/test/claim/roadmap_authority_test.dag +++ b/dag/test/claim/roadmap_authority_test.dag @@ -141,6 +141,10 @@ fn id_count(id: RoadmapNodeId) -> Int { nodes() |> filter(n => n.node == id) |> count } +fn active_id_exists(id: RoadmapNodeId) -> Bool { + active_nodes() |> any(n => n.node == id) +} + fn edge_exists(child: String, parent: String) -> Bool { edges() |> any(e => e.child == child && e.parent == parent) } @@ -253,9 +257,13 @@ test fn witness_every_declared_row_is_complete_unsigned_ticket() -> Bool { test fn witness_active_set_is_declared_minus_accepted() -> Bool { let accepted = accepted_roadmap_node_ids() - count(accepted) == 2 + count(accepted) == 6 && (accepted |> any(a => a == "namespace-occurrence-transport")) && (accepted |> any(a => a == "pderive-typesafe-nullary-reflection")) + && (accepted |> any(a => a == "2-scm-git-upstream-model")) + && (accepted |> any(a => a == "2-scm-mercurial-upstream-model")) + && (accepted |> any(a => a == "2-scm-pijul-upstream-model")) + && (accepted |> any(a => a == "2-claim-indexed-evidence")) && count(active_nodes()) == count(nodes()) - count(accepted) && all(active_nodes(), n => !(accepted |> any(a => a == n.node))) && all(accepted, a => id_exists(id: a)) @@ -308,10 +316,16 @@ test fn witness_accepted_parent_discharges_active_dependency() -> Bool { let act = active_edges() !(act |> any(e => e.child == "namespace-canonical-binding" && e.parent == "namespace-occurrence-transport")) && !(act |> any(e => e.child == "pderive-static-supplemental-contract" && e.parent == "pderive-typesafe-nullary-reflection")) + && !(act |> any(e => e.child == "2-scm-compatibility-shape")) && is_top_level(edges: act, node: "namespace-canonical-binding") && is_top_level(edges: act, node: "pderive-static-supplemental-contract") + && is_top_level(edges: act, node: "2-scm-compatibility-shape") && edge_exists(child: "namespace-canonical-binding", parent: "namespace-occurrence-transport") && edge_exists(child: "pderive-static-supplemental-contract", parent: "pderive-typesafe-nullary-reflection") + && edge_exists(child: "2-scm-compatibility-shape", parent: "2-scm-git-upstream-model") + && edge_exists(child: "2-scm-compatibility-shape", parent: "2-scm-mercurial-upstream-model") + && edge_exists(child: "2-scm-compatibility-shape", parent: "2-scm-pijul-upstream-model") + && edge_exists(child: "2-scm-compatibility-shape", parent: "2-claim-indexed-evidence") } fn exit_line_bound_to(l: V1FinishLine, node: String) -> Bool { @@ -510,6 +524,7 @@ test fn witness_product_roots_have_no_false_roadmap_tool_dependency() -> Bool { data scm_prerequisite_witness_focus_note: String = "Projected UNFOCUSED deliberately. This claim is about which lanes the AUTHORITY declares active, and it happens to read the markdown to check it. Left on the focused projection it would silently become a claim about the current view — going red whenever someone focused the page, reporting a roadmap defect where none exists. NoFocus keeps the claim measuring what it names." test fn witness_only_requested_scm_compatibility_slice_is_active() -> Bool { + let accepted = accepted_roadmap_node_ids() let out = serialize_markdown_source( doc: project_roadmap_to_markdown( doc: roadmap_authority_for(focus: NoFocus), @@ -520,14 +535,23 @@ test fn witness_only_requested_scm_compatibility_slice_is_active() -> Bool { && string_contains(s: out, pattern: "(docs/plans/dag-scm-product-strategy.md)") && string_contains(s: out, pattern: "(docs/plans/node-subtree-visibility-grants.md)") && node_has_carrier_path(path: "docs/plans/dag-scm-design.md") - && node_count_with_carrier_path(path: "docs/plans/dag-scm-design.md") == 1 + && node_count_with_carrier_path(path: "docs/plans/dag-scm-design.md") == 5 && !node_has_carrier_path(path: "docs/plans/dag-scm-product-strategy.md") && !node_has_carrier_path(path: "docs/plans/node-subtree-visibility-grants.md") - && !id_exists(id: "2-scm-git-upstream-model") - && !id_exists(id: "2-scm-mercurial-upstream-model") - && !id_exists(id: "2-scm-pijul-upstream-model") - && !id_exists(id: "2-claim-indexed-evidence") + && id_exists(id: "2-scm-git-upstream-model") + && id_exists(id: "2-scm-mercurial-upstream-model") + && id_exists(id: "2-scm-pijul-upstream-model") + && id_exists(id: "2-claim-indexed-evidence") && id_exists(id: "2-scm-compatibility-shape") + && !active_id_exists(id: "2-scm-git-upstream-model") + && !active_id_exists(id: "2-scm-mercurial-upstream-model") + && !active_id_exists(id: "2-scm-pijul-upstream-model") + && !active_id_exists(id: "2-claim-indexed-evidence") + && active_id_exists(id: "2-scm-compatibility-shape") + && (accepted |> any(id => id == "2-scm-git-upstream-model")) + && (accepted |> any(id => id == "2-scm-mercurial-upstream-model")) + && (accepted |> any(id => id == "2-scm-pijul-upstream-model")) + && (accepted |> any(id => id == "2-claim-indexed-evidence")) && !id_exists(id: "2-scm-node-merge") && !id_exists(id: "2-scm-design-partner-shadow") } diff --git a/dag/test/claim/roadmap_page_witness_test.dag b/dag/test/claim/roadmap_page_witness_test.dag index 0ad4fd02b48..f08f85ce926 100644 --- a/dag/test/claim/roadmap_page_witness_test.dag +++ b/dag/test/claim/roadmap_page_witness_test.dag @@ -86,7 +86,7 @@ test fn witness_authority_shows_finish_line_progress() -> Bool { let empty = empty_doc_html() string_contains(s: authority, pattern: "class=\"finish-line-progress\"") && string_contains(s: authority, pattern: "v1 exit: four finish lines") - && string_contains(s: authority, pattern: "62 declared · 2 accepted · 60 active") + && string_contains(s: authority, pattern: "63 declared · 6 accepted · 57 active") && string_contains(s: authority, pattern: "Compiler fixed point") && string_contains(s: authority, pattern: "Interpreter deleted") && string_contains(s: authority, pattern: "Products v1-free") diff --git a/dag/test/manual/roadmap_digest_probe.dag b/dag/test/manual/roadmap_digest_probe.dag deleted file mode 100644 index 5895ca52ccc..00000000000 --- a/dag/test/manual/roadmap_digest_probe.dag +++ /dev/null @@ -1,17 +0,0 @@ -module test.manual.roadmap_digest_probe - -import std.types { String } -import v2.std.optional { Present, Absent } -import gunbc.roadmap_authority { declared_roadmap_nodes } -import gunbc.roadmap_model { node_criteria_digest } - -fn main(id: String) -> String { - match declared_roadmap_nodes() |> filter(node => node.node == id) |> first { - Present { value: node } => - match node_criteria_digest(rn: node) { - Present { value: digest } => digest as String - Absent => "criteria-missing" - } - Absent => "node-missing" - } -} From 9d576ad571731cd479474bbec63ea31543ea4acf Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Wed, 29 Jul 2026 06:45:11 +0000 Subject: [PATCH 14/23] WIP: business --- .../scm_compatibility_shape_witness_test.dag | 129 ++++++++++-------- 1 file changed, 74 insertions(+), 55 deletions(-) diff --git a/dag/test/claim/scm_compatibility_shape_witness_test.dag b/dag/test/claim/scm_compatibility_shape_witness_test.dag index f24e5a1372f..ad5ec7ed736 100644 --- a/dag/test/claim/scm_compatibility_shape_witness_test.dag +++ b/dag/test/claim/scm_compatibility_shape_witness_test.dag @@ -18,6 +18,30 @@ import gunbc.native_scm_interaction_contract { native_scm_primary_label, native_scm_attach_projection, } +import gunbc.scm_compatibility.git { + GitCompatibilityBound, + GitCompatibilityBindingRefused, + git_compatibility_projection_handler, +} +import gunbc.scm_compatibility.mercurial { + MercurialCompatibilityBound, + MercurialCompatibilityBindingRefused, + mercurial_compatibility_projection_handler, +} +import gunbc.scm_compatibility.pijul { + PijulCompatibilityBound, + PijulCompatibilityBindingRefused, + pijul_compatibility_projection_handler, +} +import test.claim.scm_compatibility_git_witness { + git_fixture_binding, +} +import test.claim.scm_compatibility_mercurial_witness { + mercurial_fixture_binding, +} +import test.claim.scm_compatibility_pijul_witness { + pijul_fixture_binding, +} data live_tree_disposition: LiveTreeDisposition = SubstrateInputsOnly type SyntheticFourthReceipt { @@ -84,27 +108,6 @@ fn synthetic_projection( ) } -fn named_fixture_projection( - realization: NonEmptyStr, - target: NonEmptyStr, - generation: NonEmptyStr, -) -> CompatibilityProjectionReceipt { - let synthetic = synthetic_projection( - target: target, - generation: generation, - ) - CompatibilityProjectionReceipt { - realization: realization, - target: synthetic.target, - generation_evidence: synthetic.generation_evidence, - capture: synthetic.capture, - projection: synthetic.projection, - read_back: synthetic.read_back, - advance: synthetic.advance, - fidelity: synthetic.fidelity, - } -} - test fn witness_fourth_realization_adds_handler_without_primary_edit() -> Bool { let original = native_scm_receipt_for( scenario: TwoIndependentChangesLand, @@ -165,38 +168,54 @@ test fn witness_one_c0_fixture_accepts_three_realization_receipts() -> Bool { let original = native_scm_receipt_for( scenario: TwoIndependentChangesLand, ) - let with_git = native_scm_attach_projection( - receipt: original, - projection: named_fixture_projection( - realization: "git-r0", - target: "refs/heads/main", - generation: "git-generation", - ), - ) - let with_mercurial = native_scm_attach_projection( - receipt: with_git, - projection: named_fixture_projection( - realization: "mercurial-r0", - target: "default", - generation: "mercurial-generation", - ), - ) - let with_all = native_scm_attach_projection( - receipt: with_mercurial, - projection: named_fixture_projection( - realization: "pijul-r0", - target: "main", - generation: "pijul-generation", - ), - ) - with_all.identity == original.identity - && with_all.transition == original.transition - && with_all.primary == original.primary - && count(with_all.projections.realizations) == 3 - && with_all.projections.realizations - |> any(row => row.realization == "git-r0") - && with_all.projections.realizations - |> any(row => row.realization == "mercurial-r0") - && with_all.projections.realizations - |> any(row => row.realization == "pijul-r0") + match git_fixture_binding() { + GitCompatibilityBindingRefused { cause: _ } => false + GitCompatibilityBound { receipt: git_receipt } => { + let git_projection = compatibility_projection_from_handler( + handler: git_compatibility_projection_handler(), + receipt: git_receipt, + ) + let with_git = native_scm_attach_projection( + receipt: original, + projection: git_projection, + ) + match mercurial_fixture_binding() { + MercurialCompatibilityBindingRefused { cause: _ } => false + MercurialCompatibilityBound { receipt: mercurial_receipt } => { + let mercurial_projection = compatibility_projection_from_handler( + handler: mercurial_compatibility_projection_handler(), + receipt: mercurial_receipt, + ) + let with_mercurial = native_scm_attach_projection( + receipt: with_git, + projection: mercurial_projection, + ) + match pijul_fixture_binding() { + PijulCompatibilityBindingRefused { cause: _ } => false + PijulCompatibilityBound { receipt: pijul_receipt } => { + let pijul_projection = compatibility_projection_from_handler( + handler: pijul_compatibility_projection_handler(), + receipt: pijul_receipt, + ) + let with_all = native_scm_attach_projection( + receipt: with_mercurial, + projection: pijul_projection, + ) + with_all.identity == original.identity + && with_all.transition == original.transition + && with_all.primary == original.primary + && native_scm_primary_label(primary: with_all.primary) == "Landed" + && count(with_all.projections.realizations) == 3 + && git_projection.realization == "git-r0" + && git_projection.target == "refs/heads/main" + && mercurial_projection.realization == "mercurial-r0" + && mercurial_projection.target == "default" + && pijul_projection.realization == "pijul-r0" + && pijul_projection.target == "main" + } + } + } + } + } + } } From 4cb02f2d0f30c5cafcc32197a5fc5051e9096d67 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Wed, 29 Jul 2026 06:55:42 +0000 Subject: [PATCH 15/23] WIP: business --- .../claim/git_upstream_model_witness_test.dag | 24 ++++++++++++++----- .../mercurial_upstream_model_witness_test.dag | 6 ++++- .../pijul_upstream_model_witness_test.dag | 22 +++++++++++++---- .../scm_compatibility_git_witness_test.dag | 16 ++++++------- ...m_compatibility_mercurial_witness_test.dag | 8 +++---- .../scm_compatibility_pijul_witness_test.dag | 8 +++---- 6 files changed, 56 insertions(+), 28 deletions(-) diff --git a/dag/test/claim/git_upstream_model_witness_test.dag b/dag/test/claim/git_upstream_model_witness_test.dag index 95b9efb269c..2080ed26e65 100644 --- a/dag/test/claim/git_upstream_model_witness_test.dag +++ b/dag/test/claim/git_upstream_model_witness_test.dag @@ -332,7 +332,7 @@ fn fixture_wire_entries() -> List { ] } -fn fixture_tree() -> Tree { +fn git_compatibility_fixture_tree() -> Tree { Tree { entries: [ SymlinkEntry { name: name_symlink, oid: sha1_blob_symlink }, @@ -345,6 +345,10 @@ fn fixture_tree() -> Tree { } } +fn fixture_tree() -> Tree { + git_compatibility_fixture_tree() +} + fn fixture_content_address( oid: GitObjectId, object: StoreObject, @@ -443,7 +447,7 @@ fn fixture_objects() -> List { ), fixture_stored_object( oid: sha1_root_tree, - object: ObjectTree { tree: fixture_tree() }, + object: ObjectTree { tree: git_compatibility_fixture_tree() }, ), fixture_stored_object( oid: sha1_parent_commit, @@ -484,8 +488,8 @@ fn fixture_objects() -> List { ] } -fn fixture_repository() -> GitRepositoryState { - let decoded = fixture_tree() +fn git_compatibility_fixture_repository() -> GitRepositoryState { + let decoded = git_compatibility_fixture_tree() GitRepositoryState { object_format: GitObjectFormatSha1, objects: fixture_objects(), @@ -572,6 +576,10 @@ fn fixture_repository() -> GitRepositoryState { } } +fn fixture_repository() -> GitRepositoryState { + git_compatibility_fixture_repository() +} + test fn witness_git_tree_modes_and_raw_paths_decode_without_collapse() -> Bool { match git_decode_tree(entries: fixture_wire_entries()) { GitTreeDecodeRefused { cause: _ } => false @@ -827,8 +835,8 @@ test fn witness_git_bounded_fixture_projects_declared_fragment() -> Bool { } } -fn fixture_read_back_observation() -> GitR0ReadBackObservation { - let repo = fixture_repository() +fn git_compatibility_fixture_read_back_observation() -> GitR0ReadBackObservation { + let repo = git_compatibility_fixture_repository() GitR0ReadBackObservation { git_version: "git version 2.39.5", object_format: GitObjectFormatSha1, @@ -842,6 +850,10 @@ fn fixture_read_back_observation() -> GitR0ReadBackObservation { } } +fn fixture_read_back_observation() -> GitR0ReadBackObservation { + git_compatibility_fixture_read_back_observation() +} + test fn witness_git_empty_commit_and_tag_messages_are_representable() -> Bool { let empty = octets_bytes(o: []) let commit = ObjectCommit { diff --git a/dag/test/claim/mercurial_upstream_model_witness_test.dag b/dag/test/claim/mercurial_upstream_model_witness_test.dag index f82f4575700..77e39eb186b 100644 --- a/dag/test/claim/mercurial_upstream_model_witness_test.dag +++ b/dag/test/claim/mercurial_upstream_model_witness_test.dag @@ -320,10 +320,14 @@ fn fixture_projection_contents() -> MercurialRepositoryProjectionContents { ) } -fn fixture_projection() -> MercurialRepositoryProjection { +fn mercurial_compatibility_fixture_projection() -> MercurialRepositoryProjection { fixture_projection_with_local_revisions(local_revisions: local_revisions_a()) } +fn fixture_projection() -> MercurialRepositoryProjection { + mercurial_compatibility_fixture_projection() +} + fn projection_with_phases( projection: MercurialRepositoryProjection, phases: List, diff --git a/dag/test/claim/pijul_upstream_model_witness_test.dag b/dag/test/claim/pijul_upstream_model_witness_test.dag index f394454dbad..d1900015714 100644 --- a/dag/test/claim/pijul_upstream_model_witness_test.dag +++ b/dag/test/claim/pijul_upstream_model_witness_test.dag @@ -256,7 +256,7 @@ fn fixture_pristine() -> PijulPristineState { } } -fn fixture_tree() -> PijulTree { +fn pijul_compatibility_fixture_tree() -> PijulTree { PijulTree { entries: [ PijulTreeEntry { @@ -269,6 +269,10 @@ fn fixture_tree() -> PijulTree { } } +fn fixture_tree() -> PijulTree { + pijul_compatibility_fixture_tree() +} + fn fixture_working_copy() -> PijulWorkingCopy { PijulWorkingCopy { entries: [ @@ -321,26 +325,34 @@ fn fixture_channels() -> List { ] } -fn fixture_repository() -> PijulRepositoryState { +fn pijul_compatibility_fixture_repository() -> PijulRepositoryState { PijulRepositoryState { changes: fixture_changes(), pristine: fixture_pristine(), - tree: fixture_tree(), + tree: pijul_compatibility_fixture_tree(), working_copy: fixture_working_copy(), channels: fixture_channels(), current_channel: "main", } } -fn fixture_projection() -> PijulRepositoryProjection { +fn fixture_repository() -> PijulRepositoryState { + pijul_compatibility_fixture_repository() +} + +fn pijul_compatibility_fixture_projection() -> PijulRepositoryProjection { PijulPartialProjection { - candidate: fixture_repository(), + candidate: pijul_compatibility_fixture_repository(), missing_changes: [pijul_change_missing], missing_vertices: [pijul_vertex_missing], missing_paths: [pijul_path_missing], } } +fn fixture_projection() -> PijulRepositoryProjection { + pijul_compatibility_fixture_projection() +} + fn projection_with_channels( projection: PijulRepositoryProjection, channels: List, diff --git a/dag/test/claim/scm_compatibility_git_witness_test.dag b/dag/test/claim/scm_compatibility_git_witness_test.dag index a1b728acdf2..ea4cb776270 100644 --- a/dag/test/claim/scm_compatibility_git_witness_test.dag +++ b/dag/test/claim/scm_compatibility_git_witness_test.dag @@ -6,8 +6,8 @@ import extdeps.git.object_store { GitR0ReadBackObservation, } import test.claim.git_upstream_model_witness { - fixture_repository, - fixture_read_back_observation, + git_compatibility_fixture_repository, + git_compatibility_fixture_read_back_observation, sha1_root_tree, sha1_parent_commit, sha1_next_commit, @@ -43,8 +43,8 @@ data live_tree_disposition: LiveTreeDisposition = SubstrateInputsOnly fn git_fixture_binding() -> GitCompatibilityBindingOutcome { git_compatibility_bind( - repository: fixture_repository(), - read_back: fixture_read_back_observation(), + repository: git_compatibility_fixture_repository(), + read_back: git_compatibility_fixture_read_back_observation(), target: "refs/heads/main", expected_generation: sha1_parent_commit, proposed_generation: sha1_next_commit, @@ -155,7 +155,7 @@ test fn witness_git_endpoint_does_not_claim_authored_operation() -> Bool { } test fn witness_git_readback_mismatch_refuses_binding() -> Bool { - let observed = fixture_read_back_observation() + let observed = git_compatibility_fixture_read_back_observation() let wrong = GitR0ReadBackObservation { git_version: observed.git_version, object_format: observed.object_format, @@ -168,7 +168,7 @@ test fn witness_git_readback_mismatch_refuses_binding() -> Bool { unavailable: observed.unavailable, } match git_compatibility_bind( - repository: fixture_repository(), + repository: git_compatibility_fixture_repository(), read_back: wrong, target: "refs/heads/main", expected_generation: sha1_parent_commit, @@ -181,8 +181,8 @@ test fn witness_git_readback_mismatch_refuses_binding() -> Bool { test fn witness_git_generation_derives_tree_from_commit() -> Bool { match git_compatibility_bind( - repository: fixture_repository(), - read_back: fixture_read_back_observation(), + repository: git_compatibility_fixture_repository(), + read_back: git_compatibility_fixture_read_back_observation(), target: "refs/heads/main", expected_generation: sha1_root_tree, proposed_generation: sha1_next_commit, diff --git a/dag/test/claim/scm_compatibility_mercurial_witness_test.dag b/dag/test/claim/scm_compatibility_mercurial_witness_test.dag index e96c0d0e8d3..4e6a9e2c859 100644 --- a/dag/test/claim/scm_compatibility_mercurial_witness_test.dag +++ b/dag/test/claim/scm_compatibility_mercurial_witness_test.dag @@ -7,7 +7,7 @@ import extdeps.mercurial { MercurialInaccessibleProjection, } import test.claim.mercurial_upstream_model_witness { - fixture_projection, + mercurial_compatibility_fixture_projection, } import gunbc.scm_compatibility.mercurial { MercurialCompatibilityBindingOutcome, @@ -39,14 +39,14 @@ data live_tree_disposition: LiveTreeDisposition = SubstrateInputsOnly fn mercurial_fixture_observation() -> MercurialReadBackObservation { MercurialReadBackObservation { - projection: fixture_projection(), + projection: mercurial_compatibility_fixture_projection(), observed_by: "mercurial-r1-independent-fixture", } } fn mercurial_fixture_binding() -> MercurialCompatibilityBindingOutcome { mercurial_compatibility_bind( - projection: fixture_projection(), + projection: mercurial_compatibility_fixture_projection(), target: "default", read_back: mercurial_fixture_observation(), ) @@ -142,7 +142,7 @@ test fn witness_mercurial_history_does_not_claim_authored_operation() -> Bool { test fn witness_mercurial_unavailable_readback_refuses_binding() -> Bool { match mercurial_compatibility_bind( - projection: fixture_projection(), + projection: mercurial_compatibility_fixture_projection(), target: "default", read_back: MercurialReadBackObservation { projection: MercurialInaccessibleProjection { diff --git a/dag/test/claim/scm_compatibility_pijul_witness_test.dag b/dag/test/claim/scm_compatibility_pijul_witness_test.dag index 70641ab3bc8..de0a3d4325d 100644 --- a/dag/test/claim/scm_compatibility_pijul_witness_test.dag +++ b/dag/test/claim/scm_compatibility_pijul_witness_test.dag @@ -8,7 +8,7 @@ import extdeps.pijul { pijul_upstream_version, } import test.claim.pijul_upstream_model_witness { - fixture_projection, + pijul_compatibility_fixture_projection, } import gunbc.scm_compatibility.pijul { PijulCompatibilityBindingOutcome, @@ -41,13 +41,13 @@ data live_tree_disposition: LiveTreeDisposition = SubstrateInputsOnly fn pijul_fixture_observation() -> PijulReadBackObservation { PijulReadBackObservation { pijul_version: pijul_upstream_version, - projection: fixture_projection(), + projection: pijul_compatibility_fixture_projection(), } } fn pijul_fixture_binding() -> PijulCompatibilityBindingOutcome { pijul_compatibility_bind( - projection: fixture_projection(), + projection: pijul_compatibility_fixture_projection(), target: "main", read_back: pijul_fixture_observation(), ) @@ -142,7 +142,7 @@ test fn witness_pijul_preserves_upstream_change_evidence() -> Bool { test fn witness_pijul_unavailable_readback_refuses_binding() -> Bool { match pijul_compatibility_bind( - projection: fixture_projection(), + projection: pijul_compatibility_fixture_projection(), target: "main", read_back: PijulReadBackObservation { pijul_version: pijul_upstream_version, From 7d7618593e8cbc6e18318835ae0c2031e1197d13 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Wed, 29 Jul 2026 07:05:29 +0000 Subject: [PATCH 16/23] Exercise real SCM handlers in R1 witness --- dag/gunbc/scm_compatibility/pijul.dag | 29 ++++++++++++- .../claim/git_upstream_model_witness_test.dag | 18 ++++---- .../mercurial_upstream_model_witness_test.dag | 4 +- .../pijul_upstream_model_witness_test.dag | 16 +++---- .../scm_compatibility_git_witness_test.dag | 16 +++---- ...m_compatibility_mercurial_witness_test.dag | 8 ++-- .../scm_compatibility_pijul_witness_test.dag | 43 +++++++++++++++++-- 7 files changed, 98 insertions(+), 36 deletions(-) diff --git a/dag/gunbc/scm_compatibility/pijul.dag b/dag/gunbc/scm_compatibility/pijul.dag index 068971783c9..62731dfbda0 100644 --- a/dag/gunbc/scm_compatibility/pijul.dag +++ b/dag/gunbc/scm_compatibility/pijul.dag @@ -3,6 +3,7 @@ module gunbc.scm_compatibility.pijul import std.types { NonEmptyStr } import v2.std.optional { Present, Absent } import extdeps.pijul { + PijulUpstreamVersion, PijulChannelName, PijulChannelStateIdentity, PijulRepositoryProjection, @@ -135,6 +136,30 @@ fn pijul_compatibility_fidelity() -> CompatibilityFidelityProfile { } } +fn pijul_compatibility_read_back_handle( + version: PijulUpstreamVersion, +) -> NonEmptyStr { + concat( + "pijul-readback:", + concat( + to_string(version.major), + concat( + ".", + concat( + to_string(version.minor), + concat( + ".", + concat( + to_string(version.patch), + concat("-beta.", to_string(version.beta)), + ), + ), + ), + ), + ), + ) +} + fn pijul_compatibility_projection_receipt( receipt: PijulCompatibilityReceipt, ) -> CompatibilityProjectionReceipt { @@ -147,7 +172,9 @@ fn pijul_compatibility_projection_receipt( generation_evidence: generation, capture: CompatibilityUpstreamChangeEvidenceCaptured, projection: concat("pijul-channel-state:", generation), - read_back: concat("pijul-readback:", generation), + read_back: pijul_compatibility_read_back_handle( + version: receipt.read_back.pijul_version, + ), advance: CompatibilityAdvanceUnavailable { cause: reason }, fidelity: pijul_compatibility_fidelity(), } diff --git a/dag/test/claim/git_upstream_model_witness_test.dag b/dag/test/claim/git_upstream_model_witness_test.dag index 2080ed26e65..3972f51694f 100644 --- a/dag/test/claim/git_upstream_model_witness_test.dag +++ b/dag/test/claim/git_upstream_model_witness_test.dag @@ -332,7 +332,7 @@ fn fixture_wire_entries() -> List { ] } -fn git_compatibility_fixture_tree() -> Tree { +fn git_r0_fixture_tree() -> Tree { Tree { entries: [ SymlinkEntry { name: name_symlink, oid: sha1_blob_symlink }, @@ -346,7 +346,7 @@ fn git_compatibility_fixture_tree() -> Tree { } fn fixture_tree() -> Tree { - git_compatibility_fixture_tree() + git_r0_fixture_tree() } fn fixture_content_address( @@ -447,7 +447,7 @@ fn fixture_objects() -> List { ), fixture_stored_object( oid: sha1_root_tree, - object: ObjectTree { tree: git_compatibility_fixture_tree() }, + object: ObjectTree { tree: git_r0_fixture_tree() }, ), fixture_stored_object( oid: sha1_parent_commit, @@ -488,8 +488,8 @@ fn fixture_objects() -> List { ] } -fn git_compatibility_fixture_repository() -> GitRepositoryState { - let decoded = git_compatibility_fixture_tree() +fn git_r0_fixture_repository() -> GitRepositoryState { + let decoded = git_r0_fixture_tree() GitRepositoryState { object_format: GitObjectFormatSha1, objects: fixture_objects(), @@ -577,7 +577,7 @@ fn git_compatibility_fixture_repository() -> GitRepositoryState { } fn fixture_repository() -> GitRepositoryState { - git_compatibility_fixture_repository() + git_r0_fixture_repository() } test fn witness_git_tree_modes_and_raw_paths_decode_without_collapse() -> Bool { @@ -835,8 +835,8 @@ test fn witness_git_bounded_fixture_projects_declared_fragment() -> Bool { } } -fn git_compatibility_fixture_read_back_observation() -> GitR0ReadBackObservation { - let repo = git_compatibility_fixture_repository() +fn git_r0_fixture_read_back_observation() -> GitR0ReadBackObservation { + let repo = git_r0_fixture_repository() GitR0ReadBackObservation { git_version: "git version 2.39.5", object_format: GitObjectFormatSha1, @@ -851,7 +851,7 @@ fn git_compatibility_fixture_read_back_observation() -> GitR0ReadBackObservation } fn fixture_read_back_observation() -> GitR0ReadBackObservation { - git_compatibility_fixture_read_back_observation() + git_r0_fixture_read_back_observation() } test fn witness_git_empty_commit_and_tag_messages_are_representable() -> Bool { diff --git a/dag/test/claim/mercurial_upstream_model_witness_test.dag b/dag/test/claim/mercurial_upstream_model_witness_test.dag index 77e39eb186b..04e3343a996 100644 --- a/dag/test/claim/mercurial_upstream_model_witness_test.dag +++ b/dag/test/claim/mercurial_upstream_model_witness_test.dag @@ -320,12 +320,12 @@ fn fixture_projection_contents() -> MercurialRepositoryProjectionContents { ) } -fn mercurial_compatibility_fixture_projection() -> MercurialRepositoryProjection { +fn mercurial_r0_fixture_projection() -> MercurialRepositoryProjection { fixture_projection_with_local_revisions(local_revisions: local_revisions_a()) } fn fixture_projection() -> MercurialRepositoryProjection { - mercurial_compatibility_fixture_projection() + mercurial_r0_fixture_projection() } fn projection_with_phases( diff --git a/dag/test/claim/pijul_upstream_model_witness_test.dag b/dag/test/claim/pijul_upstream_model_witness_test.dag index d1900015714..49cb338432e 100644 --- a/dag/test/claim/pijul_upstream_model_witness_test.dag +++ b/dag/test/claim/pijul_upstream_model_witness_test.dag @@ -256,7 +256,7 @@ fn fixture_pristine() -> PijulPristineState { } } -fn pijul_compatibility_fixture_tree() -> PijulTree { +fn pijul_r0_fixture_tree() -> PijulTree { PijulTree { entries: [ PijulTreeEntry { @@ -270,7 +270,7 @@ fn pijul_compatibility_fixture_tree() -> PijulTree { } fn fixture_tree() -> PijulTree { - pijul_compatibility_fixture_tree() + pijul_r0_fixture_tree() } fn fixture_working_copy() -> PijulWorkingCopy { @@ -325,11 +325,11 @@ fn fixture_channels() -> List { ] } -fn pijul_compatibility_fixture_repository() -> PijulRepositoryState { +fn pijul_r0_fixture_repository() -> PijulRepositoryState { PijulRepositoryState { changes: fixture_changes(), pristine: fixture_pristine(), - tree: pijul_compatibility_fixture_tree(), + tree: pijul_r0_fixture_tree(), working_copy: fixture_working_copy(), channels: fixture_channels(), current_channel: "main", @@ -337,12 +337,12 @@ fn pijul_compatibility_fixture_repository() -> PijulRepositoryState { } fn fixture_repository() -> PijulRepositoryState { - pijul_compatibility_fixture_repository() + pijul_r0_fixture_repository() } -fn pijul_compatibility_fixture_projection() -> PijulRepositoryProjection { +fn pijul_r0_fixture_projection() -> PijulRepositoryProjection { PijulPartialProjection { - candidate: pijul_compatibility_fixture_repository(), + candidate: pijul_r0_fixture_repository(), missing_changes: [pijul_change_missing], missing_vertices: [pijul_vertex_missing], missing_paths: [pijul_path_missing], @@ -350,7 +350,7 @@ fn pijul_compatibility_fixture_projection() -> PijulRepositoryProjection { } fn fixture_projection() -> PijulRepositoryProjection { - pijul_compatibility_fixture_projection() + pijul_r0_fixture_projection() } fn projection_with_channels( diff --git a/dag/test/claim/scm_compatibility_git_witness_test.dag b/dag/test/claim/scm_compatibility_git_witness_test.dag index ea4cb776270..5082fc0531f 100644 --- a/dag/test/claim/scm_compatibility_git_witness_test.dag +++ b/dag/test/claim/scm_compatibility_git_witness_test.dag @@ -6,8 +6,8 @@ import extdeps.git.object_store { GitR0ReadBackObservation, } import test.claim.git_upstream_model_witness { - git_compatibility_fixture_repository, - git_compatibility_fixture_read_back_observation, + git_r0_fixture_repository, + git_r0_fixture_read_back_observation, sha1_root_tree, sha1_parent_commit, sha1_next_commit, @@ -43,8 +43,8 @@ data live_tree_disposition: LiveTreeDisposition = SubstrateInputsOnly fn git_fixture_binding() -> GitCompatibilityBindingOutcome { git_compatibility_bind( - repository: git_compatibility_fixture_repository(), - read_back: git_compatibility_fixture_read_back_observation(), + repository: git_r0_fixture_repository(), + read_back: git_r0_fixture_read_back_observation(), target: "refs/heads/main", expected_generation: sha1_parent_commit, proposed_generation: sha1_next_commit, @@ -155,7 +155,7 @@ test fn witness_git_endpoint_does_not_claim_authored_operation() -> Bool { } test fn witness_git_readback_mismatch_refuses_binding() -> Bool { - let observed = git_compatibility_fixture_read_back_observation() + let observed = git_r0_fixture_read_back_observation() let wrong = GitR0ReadBackObservation { git_version: observed.git_version, object_format: observed.object_format, @@ -168,7 +168,7 @@ test fn witness_git_readback_mismatch_refuses_binding() -> Bool { unavailable: observed.unavailable, } match git_compatibility_bind( - repository: git_compatibility_fixture_repository(), + repository: git_r0_fixture_repository(), read_back: wrong, target: "refs/heads/main", expected_generation: sha1_parent_commit, @@ -181,8 +181,8 @@ test fn witness_git_readback_mismatch_refuses_binding() -> Bool { test fn witness_git_generation_derives_tree_from_commit() -> Bool { match git_compatibility_bind( - repository: git_compatibility_fixture_repository(), - read_back: git_compatibility_fixture_read_back_observation(), + repository: git_r0_fixture_repository(), + read_back: git_r0_fixture_read_back_observation(), target: "refs/heads/main", expected_generation: sha1_root_tree, proposed_generation: sha1_next_commit, diff --git a/dag/test/claim/scm_compatibility_mercurial_witness_test.dag b/dag/test/claim/scm_compatibility_mercurial_witness_test.dag index 4e6a9e2c859..8e3b8f50fee 100644 --- a/dag/test/claim/scm_compatibility_mercurial_witness_test.dag +++ b/dag/test/claim/scm_compatibility_mercurial_witness_test.dag @@ -7,7 +7,7 @@ import extdeps.mercurial { MercurialInaccessibleProjection, } import test.claim.mercurial_upstream_model_witness { - mercurial_compatibility_fixture_projection, + mercurial_r0_fixture_projection, } import gunbc.scm_compatibility.mercurial { MercurialCompatibilityBindingOutcome, @@ -39,14 +39,14 @@ data live_tree_disposition: LiveTreeDisposition = SubstrateInputsOnly fn mercurial_fixture_observation() -> MercurialReadBackObservation { MercurialReadBackObservation { - projection: mercurial_compatibility_fixture_projection(), + projection: mercurial_r0_fixture_projection(), observed_by: "mercurial-r1-independent-fixture", } } fn mercurial_fixture_binding() -> MercurialCompatibilityBindingOutcome { mercurial_compatibility_bind( - projection: mercurial_compatibility_fixture_projection(), + projection: mercurial_r0_fixture_projection(), target: "default", read_back: mercurial_fixture_observation(), ) @@ -142,7 +142,7 @@ test fn witness_mercurial_history_does_not_claim_authored_operation() -> Bool { test fn witness_mercurial_unavailable_readback_refuses_binding() -> Bool { match mercurial_compatibility_bind( - projection: mercurial_compatibility_fixture_projection(), + projection: mercurial_r0_fixture_projection(), target: "default", read_back: MercurialReadBackObservation { projection: MercurialInaccessibleProjection { diff --git a/dag/test/claim/scm_compatibility_pijul_witness_test.dag b/dag/test/claim/scm_compatibility_pijul_witness_test.dag index de0a3d4325d..a213ca2b747 100644 --- a/dag/test/claim/scm_compatibility_pijul_witness_test.dag +++ b/dag/test/claim/scm_compatibility_pijul_witness_test.dag @@ -3,12 +3,13 @@ module test.claim.scm_compatibility_pijul_witness import std.types { Bool } import v2.std.live_tree { LiveTreeDisposition, SubstrateInputsOnly } import extdeps.pijul { + PijulUpstreamVersion, PijulReadBackObservation, PijulInaccessibleProjection, pijul_upstream_version, } import test.claim.pijul_upstream_model_witness { - pijul_compatibility_fixture_projection, + pijul_r0_fixture_projection, } import gunbc.scm_compatibility.pijul { PijulCompatibilityBindingOutcome, @@ -41,13 +42,13 @@ data live_tree_disposition: LiveTreeDisposition = SubstrateInputsOnly fn pijul_fixture_observation() -> PijulReadBackObservation { PijulReadBackObservation { pijul_version: pijul_upstream_version, - projection: pijul_compatibility_fixture_projection(), + projection: pijul_r0_fixture_projection(), } } fn pijul_fixture_binding() -> PijulCompatibilityBindingOutcome { pijul_compatibility_bind( - projection: pijul_compatibility_fixture_projection(), + projection: pijul_r0_fixture_projection(), target: "main", read_back: pijul_fixture_observation(), ) @@ -140,9 +141,43 @@ test fn witness_pijul_preserves_upstream_change_evidence() -> Bool { } } +test fn witness_pijul_readback_identity_comes_from_observation() -> Bool { + match pijul_fixture_binding() { + PijulCompatibilityBindingRefused { cause: _ } => false + PijulCompatibilityBound { receipt: expected } => + match pijul_compatibility_bind( + projection: pijul_r0_fixture_projection(), + target: "main", + read_back: PijulReadBackObservation { + pijul_version: PijulUpstreamVersion { + major: 1, + minor: 0, + patch: 0, + beta: 21, + }, + projection: pijul_r0_fixture_projection(), + }, + ) { + PijulCompatibilityBindingRefused { cause: _ } => false + PijulCompatibilityBound { receipt: other_observer } => { + let expected_projection = compatibility_projection_from_handler( + handler: pijul_compatibility_projection_handler(), + receipt: expected, + ) + let other_projection = compatibility_projection_from_handler( + handler: pijul_compatibility_projection_handler(), + receipt: other_observer, + ) + expected_projection.generation_evidence == other_projection.generation_evidence + && expected_projection.read_back != other_projection.read_back + } + } + } +} + test fn witness_pijul_unavailable_readback_refuses_binding() -> Bool { match pijul_compatibility_bind( - projection: pijul_compatibility_fixture_projection(), + projection: pijul_r0_fixture_projection(), target: "main", read_back: PijulReadBackObservation { pijul_version: pijul_upstream_version, From f49b95e8c5935ab0a736c3e15d40d51da1cd014d Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Wed, 29 Jul 2026 07:13:42 +0000 Subject: [PATCH 17/23] WIP: business --- dag/test/claim/pijul_upstream_model_witness_test.dag | 4 ---- 1 file changed, 4 deletions(-) diff --git a/dag/test/claim/pijul_upstream_model_witness_test.dag b/dag/test/claim/pijul_upstream_model_witness_test.dag index 49cb338432e..958f94487a8 100644 --- a/dag/test/claim/pijul_upstream_model_witness_test.dag +++ b/dag/test/claim/pijul_upstream_model_witness_test.dag @@ -269,10 +269,6 @@ fn pijul_r0_fixture_tree() -> PijulTree { } } -fn fixture_tree() -> PijulTree { - pijul_r0_fixture_tree() -} - fn fixture_working_copy() -> PijulWorkingCopy { PijulWorkingCopy { entries: [ From 32170cade352b05bbd52f0adb92eff98e89487bf Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Wed, 29 Jul 2026 16:26:39 +0000 Subject: [PATCH 18/23] WIP: business --- ROADMAP.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ROADMAP.md b/ROADMAP.md index 04c037f40e3..a09e2858541 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -8,9 +8,9 @@ Parked context (non-dispatchable): [compiler algorithm survey](docs/plans/compil ## Active deliverables — dependency order -The graph has ten lanes: SCM prerequisites · namespace · P-derive · observation · placement · v1 exit (four finish lines: compiler fixed point, interpreter deleted, products v1-free, zero hand-maintained Rust) · shell · roadmap runtime · fleet/hygiene · hermetic toolchain. The three SCM R0 models, the P−1 evidence carrier, and the toolchain pin model are independent roots; compatibility extraction and later SCM/product lanes remain parked. The P-derive receipt feeds the emitter fixed point, so the v1 chain nests under it. Node fields define boundary, first slice, RED control, exclusions, owner, and handback. +The graph has ten lanes: SCM compatibility · namespace · P-derive · observation · placement · v1 exit (four finish lines: compiler fixed point, interpreter deleted, products v1-free, zero hand-maintained Rust) · shell · roadmap runtime · fleet/hygiene · hermetic toolchain. The three independent SCM R0 models and P−1 evidence carrier are landed prerequisites; R1 compatibility-shape extraction is the active SCM slice, while semantic-kernel and later product lanes remain parked. The toolchain pin model is an independent root. The P-derive receipt feeds the emitter fixed point, so the v1 chain nests under it. Node fields define boundary, first slice, RED control, exclusions, owner, and handback. -**Focused view — the v1 → v2 emitter exit lane.** 37 active deliverable(s) in other lanes are declared in the authority and hidden here; nothing is deleted or parked by focusing. Clear `roadmap_focus_selection` in `dag/gunbc/roadmap_authority.dag` to restore the full page. Hidden lanes remain readable through their carriers: [docs/plans/dag-scm-design.md](docs/plans/dag-scm-design.md) · [docs/plans/namespace-unique-on-chain-operational-plan.md](docs/plans/namespace-unique-on-chain-operational-plan.md) · [dag/gunbc/plans/cli_run_hollowing_plan.dag](dag/gunbc/plans/cli_run_hollowing_plan.dag) · [docs/plans/progress-observation-design.md](docs/plans/progress-observation-design.md) · [docs/plans/ci-two-tier-placement-redesign.md](docs/plans/ci-two-tier-placement-redesign.md) · [dag/gunbc/v1_deletion_plan.dag](dag/gunbc/v1_deletion_plan.dag) · [docs/plans/shell-to-dag-residual-census-and-arc-completion.md](docs/plans/shell-to-dag-residual-census-and-arc-completion.md) · [docs/plans/roadmap-workspace-ux-plan.md](docs/plans/roadmap-workspace-ux-plan.md) · [docs/plans/host-converge-inventory.md](docs/plans/host-converge-inventory.md) · [docs/runbooks/bmc-redfish-operator-access.md](docs/runbooks/bmc-redfish-operator-access.md) · [docs/plans/host-effect-orchestration.md](docs/plans/host-effect-orchestration.md) · [docs/plans/gunbc-served-dashboard-design.md](docs/plans/gunbc-served-dashboard-design.md) · [docs/plans/fleet-acceptance-criteria.md](docs/plans/fleet-acceptance-criteria.md) · [docs/plans/hermetic-tool-provisioning-design.md](docs/plans/hermetic-tool-provisioning-design.md). +**Focused view — the v1 → v2 emitter exit lane.** 34 active deliverable(s) in other lanes are declared in the authority and hidden here; nothing is deleted or parked by focusing. Clear `roadmap_focus_selection` in `dag/gunbc/roadmap_authority.dag` to restore the full page. Hidden lanes remain readable through their carriers: [docs/plans/dag-scm-design.md](docs/plans/dag-scm-design.md) · [docs/plans/namespace-unique-on-chain-operational-plan.md](docs/plans/namespace-unique-on-chain-operational-plan.md) · [dag/gunbc/plans/cli_run_hollowing_plan.dag](dag/gunbc/plans/cli_run_hollowing_plan.dag) · [docs/plans/progress-observation-design.md](docs/plans/progress-observation-design.md) · [docs/plans/ci-two-tier-placement-redesign.md](docs/plans/ci-two-tier-placement-redesign.md) · [dag/gunbc/v1_deletion_plan.dag](dag/gunbc/v1_deletion_plan.dag) · [docs/plans/shell-to-dag-residual-census-and-arc-completion.md](docs/plans/shell-to-dag-residual-census-and-arc-completion.md) · [docs/plans/roadmap-workspace-ux-plan.md](docs/plans/roadmap-workspace-ux-plan.md) · [docs/plans/host-converge-inventory.md](docs/plans/host-converge-inventory.md) · [docs/runbooks/bmc-redfish-operator-access.md](docs/runbooks/bmc-redfish-operator-access.md) · [docs/plans/host-effect-orchestration.md](docs/plans/host-effect-orchestration.md) · [docs/plans/gunbc-served-dashboard-design.md](docs/plans/gunbc-served-dashboard-design.md) · [docs/plans/fleet-acceptance-criteria.md](docs/plans/fleet-acceptance-criteria.md) · [docs/plans/hermetic-tool-provisioning-design.md](docs/plans/hermetic-tool-provisioning-design.md). - [ ] **Write down which extra type requirements each generated shape needs** — For each shape we generate Rust for, record which extra requirements each of its type slots needs. 'No requirements' and 'we never said' stay different answers. Why: The generator currently guesses these, so generated Rust fails to compile in ways that look like a dozen unrelated bugs. [authority](docs/plans/v2-self-hosting.md) - [ ] **Attach those requirements to the right type, not just the right position** — Connect each recorded slot to the exact declaration it belongs to, using the name resolution work above. Why: Matching by position or by short name attaches a requirement to the wrong type whenever two types share a name or the order shifts. [authority](docs/plans/v2-self-hosting.md) From af34dc80b888c91efc4987fc73f847a4e7eda60c Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Wed, 29 Jul 2026 16:47:39 +0000 Subject: [PATCH 19/23] WIP: business --- dag/gunbc/scm_compatibility_shape.dag | 65 ++++++++++++++++++++++++++- 1 file changed, 64 insertions(+), 1 deletion(-) diff --git a/dag/gunbc/scm_compatibility_shape.dag b/dag/gunbc/scm_compatibility_shape.dag index f7f8fd001f6..9709cbce503 100644 --- a/dag/gunbc/scm_compatibility_shape.dag +++ b/dag/gunbc/scm_compatibility_shape.dag @@ -1,6 +1,11 @@ module gunbc.scm_compatibility_shape -import std.types { Bool, List, NonEmptyStr } +import std.types { Bool, ContentHash, List, NonEmptyStr, String } +import std.content_hash { + content_hash_atom, + content_hash_combine, + content_hash_tagged, +} data scm_compatibility_shape_note: NonEmptyStr = "R1 compatibility-realization shape extracted from the independently executing Git, Mercurial, and Pijul R0 boundaries. The shared carrier owns only roles demonstrated by the landed R0s: an opaque realization and target handle, a handle to native generation evidence, honest capture fidelity, realization-specific preservation/loss facts, projection plus independent read-back, and an explicit modeled-or-unavailable conditional-advance capability. Native evidence remains in adapter-specific typed receipts; this presentation projection is not a semantic, policy, repair, execution, commit, or Applied receipt. A failed projection may later be replaced idempotently by realization and target only after some external operation supplies a new independently read-back receipt. Dispatch is a generic handler value, never ScmKind or a vendor switch. A fourth realization supplies one handler and does not edit this module or the native interaction contract." @@ -10,6 +15,64 @@ type CompatibilityGenerationEvidenceHandle = NonEmptyStr where brand("Compatibil type CompatibilityProjectionHandle = NonEmptyStr where brand("CompatibilityProjectionHandle") type CompatibilityReadBackHandle = NonEmptyStr where brand("CompatibilityReadBackHandle") +fn compatibility_identity_text( + tag: NonEmptyStr, + value: String, +) -> ContentHash { + content_hash_atom( + value: concat( + tag, + concat(":", value), + ) as NonEmptyStr, + ) +} + +fn compatibility_identity_sequence( + tag: NonEmptyStr, + members: List, +) -> ContentHash { + fold( + members, + init: content_hash_atom(value: tag), + f: fn(acc, member) { + content_hash_combine(left: acc, right: member) + }, + ) +} + +fn compatibility_projection_handle( + realization: CompatibilityRealizationHandle, + state: ContentHash, +) -> CompatibilityProjectionHandle { + content_hash_tagged( + tag: concat( + "compatibility-projection:", + realization as String, + ) as NonEmptyStr, + payload: state, + ) as CompatibilityProjectionHandle +} + +fn compatibility_read_back_handle( + realization: CompatibilityRealizationHandle, + producer: NonEmptyStr, + state: ContentHash, +) -> CompatibilityReadBackHandle { + content_hash_tagged( + tag: concat( + "compatibility-readback:", + realization as String, + ) as NonEmptyStr, + payload: content_hash_combine( + left: compatibility_identity_text( + tag: "producer", + value: producer as String, + ), + right: state, + ), + ) as CompatibilityReadBackHandle +} + type CompatibilityCaptureClass = CompatibilityEndpointStateCaptured | CompatibilityUpstreamChangeEvidenceCaptured From 1ad4ed10324324044cbc326a1e5d404437d0ac2f Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Wed, 29 Jul 2026 16:58:09 +0000 Subject: [PATCH 20/23] WIP: business --- dag/gunbc/scm_compatibility/git.dag | 348 +++++++++++- dag/gunbc/scm_compatibility/mercurial.dag | 427 +++++++++++++- dag/gunbc/scm_compatibility/pijul.dag | 525 +++++++++++++++++- .../scm_compatibility_git_witness_test.dag | 49 ++ ...m_compatibility_mercurial_witness_test.dag | 34 ++ .../scm_compatibility_pijul_witness_test.dag | 51 ++ 6 files changed, 1408 insertions(+), 26 deletions(-) diff --git a/dag/gunbc/scm_compatibility/git.dag b/dag/gunbc/scm_compatibility/git.dag index 92c7862ce53..7b4213d9aa7 100644 --- a/dag/gunbc/scm_compatibility/git.dag +++ b/dag/gunbc/scm_compatibility/git.dag @@ -1,12 +1,19 @@ module gunbc.scm_compatibility.git -import std.types { List, NonEmptyStr } -import std.integer { NonNegativeInt } +import std.types { Bool, Bytes, ContentHash, List, NonEmptyStr, String } +import std.integer { NonNegativeInt, UInt8 } +import std.bytes { bytes_octets } import extdeps.git { ObjectType } import extdeps.git.object_store { GitObjectId, GitObjectFormat, + GitObjectFormatSha1, + GitObjectFormatSha256, GitRefName, + GitRefRecord, + RefTarget, + DirectTarget, + SymbolicTarget, GitRepositoryState, GitRepositoryDecodeRefusal, StoredObject, @@ -14,6 +21,25 @@ import extdeps.git.object_store { ObjectLookupResult, GitR0Projection, GitR0ReadBackObservation, + GitTreeWireEntry, + GitIndexEntry, + GitIndexStage, + GitIndexStageNormal, + GitIndexStageBase, + GitIndexStageOurs, + GitIndexStageTheirs, + GitTreeMode, + GitRegularBlobMode, + GitExecutableBlobMode, + GitSymlinkMode, + GitSubtreeMode, + GitlinkMode, + GitWorktreeEntry, + GitWorktreeRegular, + GitWorktreeSymlink, + GitWorktreeGitlink, + GitUnavailableObject, + GitUnavailableObjectFold, GitReadBackMismatchAxis, GitModeledRefTransition, GitR0UnsupportedBoundary, @@ -41,6 +67,8 @@ import extdeps.git.object_store { git_model_update_ref_exact, git_lookup_object, git_object_id_content_hash, + git_path_octets, + git_unavailable_object_fold, git_r0_unsupported_boundary, } import gunbc.scm_compatibility_shape { @@ -53,6 +81,10 @@ import gunbc.scm_compatibility_shape { CompatibilityFidelityUnavailable, CompatibilityAdvanceModeled, CompatibilityExactCompareAndAdvance, + compatibility_identity_text, + compatibility_identity_sequence, + compatibility_projection_handle, + compatibility_read_back_handle, } data git_compatibility_binding_note: NonEmptyStr = "The Git R1 handler consumes Git's own decoded projection, independent read-back, and exact-old-OID transition model. GitObjectId, GitRefName, tree/index/worktree facts, and unsupported-boundary rows remain in GitCompatibilityReceipt; the common projection contains no Git object, ref, commit, or branch type. CompatibilityAdvanceModeled is deliberately weaker than P3's executed-and-read-back transition receipt." @@ -370,6 +402,301 @@ fn git_compatibility_bind( } } +fn git_compatibility_octets_identity( + tag: NonEmptyStr, + octets: List, +) -> ContentHash { + compatibility_identity_sequence( + tag: tag, + members: octets + |> map(octet => + compatibility_identity_text( + tag: "octet", + value: to_string(octet), + ) + ), + ) +} + +fn git_compatibility_bytes_identity( + tag: NonEmptyStr, + bytes: Bytes, +) -> ContentHash { + git_compatibility_octets_identity( + tag: tag, + octets: bytes_octets(b: bytes), + ) +} + +fn git_compatibility_object_id_identity( + oid: GitObjectId, +) -> ContentHash { + compatibility_identity_text( + tag: "git-object-id", + value: git_object_id_content_hash(oid: oid) as String, + ) +} + +fn git_compatibility_object_format_identity( + format: GitObjectFormat, +) -> ContentHash { + let label = match format { + GitObjectFormatSha1 => "sha1" + GitObjectFormatSha256 => "sha256" + } + compatibility_identity_text( + tag: "git-object-format", + value: label, + ) +} + +fn git_compatibility_tree_wire_entry_identity( + entry: GitTreeWireEntry, +) -> ContentHash { + compatibility_identity_sequence( + tag: "git-tree-wire-entry", + members: [ + compatibility_identity_text( + tag: "mode", + value: entry.mode as String, + ), + compatibility_identity_text( + tag: "object-type", + value: entry.object_type as String, + ), + git_compatibility_object_id_identity(oid: entry.oid), + git_compatibility_octets_identity( + tag: "name", + octets: entry.name.octets, + ), + ], + ) +} + +fn git_compatibility_ref_target_identity( + target: RefTarget, +) -> ContentHash { + match target { + DirectTarget { oid } => + compatibility_identity_sequence( + tag: "git-direct-target", + members: [git_compatibility_object_id_identity(oid: oid)], + ) + SymbolicTarget { ref_name } => + compatibility_identity_text( + tag: "git-symbolic-target", + value: ref_name as String, + ) + } +} + +fn git_compatibility_ref_identity( + record: GitRefRecord, +) -> ContentHash { + compatibility_identity_sequence( + tag: "git-ref", + members: [ + compatibility_identity_text( + tag: "name", + value: record.name as String, + ), + git_compatibility_ref_target_identity(target: record.target), + ], + ) +} + +fn git_compatibility_tree_mode_identity( + mode: GitTreeMode, +) -> ContentHash { + let label = match mode { + GitRegularBlobMode => "regular" + GitExecutableBlobMode => "executable" + GitSymlinkMode => "symlink" + GitSubtreeMode => "subtree" + GitlinkMode => "gitlink" + } + compatibility_identity_text( + tag: "git-tree-mode", + value: label, + ) +} + +fn git_compatibility_index_stage_identity( + stage: GitIndexStage, +) -> ContentHash { + let label = match stage { + GitIndexStageNormal => "normal" + GitIndexStageBase => "base" + GitIndexStageOurs => "ours" + GitIndexStageTheirs => "theirs" + } + compatibility_identity_text( + tag: "git-index-stage", + value: label, + ) +} + +fn git_compatibility_index_entry_identity( + entry: GitIndexEntry, +) -> ContentHash { + compatibility_identity_sequence( + tag: "git-index-entry", + members: [ + git_compatibility_octets_identity( + tag: "path", + octets: git_path_octets(path: entry.path), + ), + git_compatibility_tree_mode_identity(mode: entry.mode), + git_compatibility_object_id_identity(oid: entry.oid), + git_compatibility_index_stage_identity(stage: entry.stage), + ], + ) +} + +fn git_compatibility_worktree_entry_identity( + entry: GitWorktreeEntry, +) -> ContentHash { + match entry { + GitWorktreeRegular { path, executable, content } => + compatibility_identity_sequence( + tag: "git-worktree-regular", + members: [ + git_compatibility_octets_identity( + tag: "path", + octets: git_path_octets(path: path), + ), + compatibility_identity_text( + tag: "executable", + value: to_string(executable), + ), + git_compatibility_bytes_identity( + tag: "content", + bytes: content, + ), + ], + ) + GitWorktreeSymlink { path, target } => + compatibility_identity_sequence( + tag: "git-worktree-symlink", + members: [ + git_compatibility_octets_identity( + tag: "path", + octets: git_path_octets(path: path), + ), + git_compatibility_bytes_identity( + tag: "target", + bytes: target, + ), + ], + ) + GitWorktreeGitlink { path, checkout } => + compatibility_identity_sequence( + tag: "git-worktree-gitlink", + members: [ + git_compatibility_octets_identity( + tag: "path", + octets: git_path_octets(path: path), + ), + git_compatibility_object_id_identity(oid: checkout), + ], + ) + } +} + +fn git_compatibility_unavailable_identity( + unavailable: GitUnavailableObject, +) -> ContentHash { + git_unavailable_object_fold( + unavailable: unavailable, + fold: GitUnavailableObjectFold { + promisor: fn(oid, promisor) { + compatibility_identity_sequence( + tag: "git-promisor-unavailable", + members: [ + git_compatibility_object_id_identity(oid: oid), + compatibility_identity_text( + tag: "promisor", + value: promisor as String, + ), + ], + ) + }, + unexpected_missing: fn(oid) { + compatibility_identity_sequence( + tag: "git-unexpected-missing", + members: [git_compatibility_object_id_identity(oid: oid)], + ) + }, + corrupt: fn(oid, reason) { + compatibility_identity_sequence( + tag: "git-corrupt", + members: [ + git_compatibility_object_id_identity(oid: oid), + compatibility_identity_text( + tag: "reason", + value: reason as String, + ), + ], + ) + }, + }, + ) +} + +fn git_compatibility_observed_state_identity( + observation: GitR0ReadBackObservation, +) -> ContentHash { + compatibility_identity_sequence( + tag: "git-readback-state-v1", + members: [ + git_compatibility_object_format_identity( + format: observation.object_format, + ), + git_compatibility_object_id_identity(oid: observation.tree_oid), + compatibility_identity_sequence( + tag: "tree-entries", + members: observation.tree_entries + |> map(entry => + git_compatibility_tree_wire_entry_identity(entry: entry) + ), + ), + compatibility_identity_sequence( + tag: "tag-oids", + members: observation.tag_oids + |> map(oid => git_compatibility_object_id_identity(oid: oid)), + ), + compatibility_identity_sequence( + tag: "refs", + members: observation.refs + |> map(record => git_compatibility_ref_identity(record: record)), + ), + compatibility_identity_sequence( + tag: "index", + members: observation.index + |> map(entry => + git_compatibility_index_entry_identity(entry: entry) + ), + ), + compatibility_identity_sequence( + tag: "worktree", + members: observation.worktree + |> map(entry => + git_compatibility_worktree_entry_identity(entry: entry) + ), + ), + compatibility_identity_sequence( + tag: "unavailable", + members: observation.unavailable + |> map(unavailable => + git_compatibility_unavailable_identity( + unavailable: unavailable, + ) + ), + ), + ], + ) +} + fn git_compatibility_fidelity() -> CompatibilityFidelityProfile { CompatibilityFidelityProfile { endpoint_state: CompatibilityFidelityPreserved, @@ -394,16 +721,23 @@ fn git_compatibility_projection_receipt( receipt: GitCompatibilityReceipt, ) -> CompatibilityProjectionReceipt { let generation = git_object_id_content_hash(oid: receipt.generation) as NonEmptyStr - let projection = git_object_id_content_hash( - oid: receipt.projection.tree_oid, - ) as NonEmptyStr + let state = git_compatibility_observed_state_identity( + observation: receipt.read_back, + ) CompatibilityProjectionReceipt { realization: "git-r0", target: receipt.target as NonEmptyStr, generation_evidence: generation, capture: CompatibilityEndpointStateCaptured, - projection: projection, - read_back: concat("git-readback:", receipt.read_back.git_version), + projection: compatibility_projection_handle( + realization: "git-r0", + state: state, + ), + read_back: compatibility_read_back_handle( + realization: "git-r0", + producer: receipt.read_back.git_version, + state: state, + ), advance: CompatibilityAdvanceModeled { guarantee: CompatibilityExactCompareAndAdvance, }, diff --git a/dag/gunbc/scm_compatibility/mercurial.dag b/dag/gunbc/scm_compatibility/mercurial.dag index 6dcec642bc2..dedcd1b7a25 100644 --- a/dag/gunbc/scm_compatibility/mercurial.dag +++ b/dag/gunbc/scm_compatibility/mercurial.dag @@ -1,11 +1,34 @@ module gunbc.scm_compatibility.mercurial -import std.types { List, NonEmptyStr } +import std.types { ContentHash, List, NonEmptyStr, String } +import std.integer { UInt8 } import extdeps.mercurial { MercurialNamedBranchName, MercurialNodeId, MercurialRepositoryProjection, MercurialRepositoryState, + MercurialRepositoryCompleteness, + MercurialRepositoryCompletenessFold, + MercurialLocalRevisionEntry, + MercurialBookmark, + MercurialTag, + MercurialTagSource, + MercurialVersionedTag, + MercurialLocalTag, + MercurialPhaseEntry, + MercurialPhase, + MercurialPublic, + MercurialDraft, + MercurialSecret, + MercurialPublishingBehavior, + MercurialPublishingServer, + MercurialNonPublishingServer, + MercurialSubrepository, + MercurialPath, + MercurialEvolutionMetadata, + MercurialEvolutionNotEnabled, + MercurialEvolutionMarkers, + MercurialObsolescenceMarker, MercurialProjectionRefusal, MercurialReadBackObservation, MercurialConditionalAdvanceCapability, @@ -22,6 +45,7 @@ import extdeps.mercurial { mercurial_portable_history, mercurial_named_branch_changesets, mercurial_node_id_text, + mercurial_repository_completeness_fold, mercurial_r0_conditional_advance, } import gunbc.scm_compatibility_shape { @@ -33,10 +57,16 @@ import gunbc.scm_compatibility_shape { CompatibilityFidelityDowngraded, CompatibilityFidelityUnavailable, CompatibilityAdvanceUnavailable, + compatibility_identity_text, + compatibility_identity_sequence, + compatibility_projection_handle, + compatibility_read_back_handle, } data mercurial_compatibility_binding_note: NonEmptyStr = "The Mercurial R1 handler consumes Mercurial's own projection decoder, portable changeset identities, named-branch relation, and independent read-back assessment. Clone-local revisions, phases, bookmarks, tags, evolution, repository completeness, and node identities remain in MercurialCompatibilityReceipt. The shared carrier does not rename any of them commit, ref, or branch authority, and R0 honestly reports conditional advance as unavailable." +data mercurial_compatibility_read_back_identity_note: NonEmptyStr = "A MercurialCompatibilityReceipt is constructible by this handler only after mercurial_assess_read_back proves that the independently decoded observation equals repository. The common read-back handle therefore fingerprints that complete decoded repository state plus observed_by; it never treats the observer label itself as the state identity." + type MercurialCompatibilityReceipt { target: MercurialNamedBranchName portable_history: List @@ -171,6 +201,386 @@ fn mercurial_compatibility_history_handle( ) } +fn mercurial_compatibility_node_identity( + tag: NonEmptyStr, + node: MercurialNodeId, +) -> ContentHash { + compatibility_identity_text( + tag: tag, + value: mercurial_node_id_text(node: node), + ) +} + +fn mercurial_compatibility_octets_identity( + tag: NonEmptyStr, + octets: List, +) -> ContentHash { + compatibility_identity_sequence( + tag: tag, + members: octets + |> map(octet => + compatibility_identity_text( + tag: "octet", + value: to_string(octet), + ) + ), + ) +} + +fn mercurial_compatibility_path_identity( + tag: NonEmptyStr, + path: MercurialPath, +) -> ContentHash { + mercurial_compatibility_octets_identity( + tag: tag, + octets: path.octets, + ) +} + +fn mercurial_compatibility_local_revision_identity( + entry: MercurialLocalRevisionEntry, +) -> ContentHash { + compatibility_identity_sequence( + tag: "mercurial-local-revision", + members: [ + compatibility_identity_text( + tag: "revision", + value: to_string(entry.revision.value), + ), + mercurial_compatibility_node_identity( + tag: "changeset", + node: entry.changeset, + ), + ], + ) +} + +fn mercurial_compatibility_bookmark_identity( + bookmark: MercurialBookmark, +) -> ContentHash { + compatibility_identity_sequence( + tag: "mercurial-bookmark", + members: [ + compatibility_identity_text( + tag: "name", + value: bookmark.name as String, + ), + mercurial_compatibility_node_identity( + tag: "target", + node: bookmark.target, + ), + ], + ) +} + +fn mercurial_compatibility_tag_source_identity( + source: MercurialTagSource, +) -> ContentHash { + let label = match source { + MercurialVersionedTag => "versioned" + MercurialLocalTag => "local" + } + compatibility_identity_text( + tag: "mercurial-tag-source", + value: label, + ) +} + +fn mercurial_compatibility_tag_identity( + tag: MercurialTag, +) -> ContentHash { + compatibility_identity_sequence( + tag: "mercurial-tag", + members: [ + compatibility_identity_text( + tag: "name", + value: tag.name as String, + ), + mercurial_compatibility_node_identity( + tag: "target", + node: tag.target, + ), + mercurial_compatibility_tag_source_identity(source: tag.source), + ], + ) +} + +fn mercurial_compatibility_phase_value_identity( + phase: MercurialPhase, +) -> ContentHash { + let label = match phase { + MercurialPublic => "public" + MercurialDraft => "draft" + MercurialSecret => "secret" + } + compatibility_identity_text( + tag: "mercurial-phase", + value: label, + ) +} + +fn mercurial_compatibility_phase_identity( + entry: MercurialPhaseEntry, +) -> ContentHash { + compatibility_identity_sequence( + tag: "mercurial-phase-entry", + members: [ + mercurial_compatibility_node_identity( + tag: "changeset", + node: entry.changeset, + ), + mercurial_compatibility_phase_value_identity(phase: entry.phase), + ], + ) +} + +fn mercurial_compatibility_publishing_identity( + publishing: MercurialPublishingBehavior, +) -> ContentHash { + let label = match publishing { + MercurialPublishingServer => "publishing" + MercurialNonPublishingServer => "non-publishing" + } + compatibility_identity_text( + tag: "mercurial-publishing", + value: label, + ) +} + +fn mercurial_compatibility_subrepository_identity( + repository: MercurialSubrepository, +) -> ContentHash { + compatibility_identity_sequence( + tag: "mercurial-subrepository", + members: [ + mercurial_compatibility_path_identity( + tag: "path", + path: repository.path, + ), + compatibility_identity_text( + tag: "source", + value: repository.source as String, + ), + compatibility_identity_text( + tag: "revision", + value: repository.revision as String, + ), + ], + ) +} + +fn mercurial_compatibility_marker_identity( + marker: MercurialObsolescenceMarker, +) -> ContentHash { + compatibility_identity_sequence( + tag: "mercurial-obsolescence-marker", + members: [ + mercurial_compatibility_node_identity( + tag: "predecessor", + node: marker.predecessor, + ), + compatibility_identity_sequence( + tag: "successors", + members: marker.successors + |> map(successor => + mercurial_compatibility_node_identity( + tag: "successor", + node: successor, + ) + ), + ), + compatibility_identity_text( + tag: "operation", + value: marker.operation as String, + ), + ], + ) +} + +fn mercurial_compatibility_evolution_identity( + evolution: MercurialEvolutionMetadata, +) -> ContentHash { + match evolution { + MercurialEvolutionNotEnabled => + compatibility_identity_sequence( + tag: "mercurial-evolution-disabled", + members: [], + ) + MercurialEvolutionMarkers { markers } => + compatibility_identity_sequence( + tag: "mercurial-evolution-markers", + members: markers + |> map(marker => + mercurial_compatibility_marker_identity(marker: marker) + ), + ) + } +} + +fn mercurial_compatibility_completeness_identity( + completeness: MercurialRepositoryCompleteness, +) -> ContentHash { + mercurial_repository_completeness_fold( + completeness: completeness, + fold: MercurialRepositoryCompletenessFold { + complete: fn() { + compatibility_identity_sequence( + tag: "mercurial-complete", + members: [], + ) + }, + partial: fn( + missing_changesets, + missing_manifests, + missing_file_revisions, + ) { + compatibility_identity_sequence( + tag: "mercurial-partial", + members: [ + compatibility_identity_sequence( + tag: "missing-changesets", + members: missing_changesets + |> map(node => + mercurial_compatibility_node_identity( + tag: "changeset", + node: node, + ) + ), + ), + compatibility_identity_sequence( + tag: "missing-manifests", + members: missing_manifests + |> map(node => + mercurial_compatibility_node_identity( + tag: "manifest", + node: node, + ) + ), + ), + compatibility_identity_sequence( + tag: "missing-file-revisions", + members: missing_file_revisions + |> map(node => + mercurial_compatibility_node_identity( + tag: "file-revision", + node: node, + ) + ), + ), + ], + ) + }, + }, + ) +} + +fn mercurial_compatibility_observed_state_identity( + repository: MercurialRepositoryState, +) -> ContentHash { + let contents = repository.contents + compatibility_identity_sequence( + tag: "mercurial-readback-state-v1", + members: [ + compatibility_identity_sequence( + tag: "requirements", + members: contents.requirements.tokens + |> map(token => + compatibility_identity_text( + tag: "requirement", + value: token as String, + ) + ), + ), + compatibility_identity_sequence( + tag: "file-revisions", + members: contents.file_revisions + |> map(revision => + mercurial_compatibility_node_identity( + tag: "file-revision", + node: revision.node, + ) + ), + ), + compatibility_identity_sequence( + tag: "manifests", + members: contents.manifests + |> map(manifest => + mercurial_compatibility_node_identity( + tag: "manifest", + node: manifest.node, + ) + ), + ), + compatibility_identity_sequence( + tag: "changesets", + members: contents.changesets + |> map(changeset => + mercurial_compatibility_node_identity( + tag: "changeset", + node: changeset.node, + ) + ), + ), + compatibility_identity_sequence( + tag: "local-revisions", + members: contents.local_revisions + |> map(entry => + mercurial_compatibility_local_revision_identity(entry: entry) + ), + ), + compatibility_identity_sequence( + tag: "heads", + members: contents.heads + |> map(head => + mercurial_compatibility_node_identity( + tag: "head", + node: head.changeset, + ) + ), + ), + compatibility_identity_sequence( + tag: "bookmarks", + members: contents.bookmarks + |> map(bookmark => + mercurial_compatibility_bookmark_identity( + bookmark: bookmark, + ) + ), + ), + compatibility_identity_sequence( + tag: "tags", + members: contents.tags + |> map(tag => mercurial_compatibility_tag_identity(tag: tag)), + ), + compatibility_identity_sequence( + tag: "phases", + members: contents.phases + |> map(entry => + mercurial_compatibility_phase_identity(entry: entry) + ), + ), + mercurial_compatibility_publishing_identity( + publishing: contents.publishing, + ), + compatibility_identity_sequence( + tag: "subrepositories", + members: contents.subrepositories + |> map(subrepository => + mercurial_compatibility_subrepository_identity( + repository: subrepository, + ) + ), + ), + mercurial_compatibility_evolution_identity( + evolution: contents.evolution, + ), + mercurial_compatibility_completeness_identity( + completeness: repository.completeness, + ), + ], + ) +} + fn mercurial_compatibility_fidelity() -> CompatibilityFidelityProfile { CompatibilityFidelityProfile { endpoint_state: CompatibilityFidelityPreserved, @@ -197,6 +607,9 @@ fn mercurial_compatibility_projection_receipt( let generation = mercurial_compatibility_history_handle( history: receipt.target_history, ) + let state = mercurial_compatibility_observed_state_identity( + repository: receipt.repository, + ) match receipt.advance { MercurialConditionalAdvanceUnavailable { reason } => CompatibilityProjectionReceipt { @@ -204,10 +617,14 @@ fn mercurial_compatibility_projection_receipt( target: receipt.target as NonEmptyStr, generation_evidence: generation, capture: CompatibilityEndpointStateCaptured, - projection: concat("mercurial-projection:", generation), - read_back: concat( - "mercurial-readback:", - receipt.read_back.observed_by, + projection: compatibility_projection_handle( + realization: "mercurial-r0", + state: state, + ), + read_back: compatibility_read_back_handle( + realization: "mercurial-r0", + producer: receipt.read_back.observed_by, + state: state, ), advance: CompatibilityAdvanceUnavailable { cause: reason }, fidelity: mercurial_compatibility_fidelity(), diff --git a/dag/gunbc/scm_compatibility/pijul.dag b/dag/gunbc/scm_compatibility/pijul.dag index 62731dfbda0..a5bc25b08ee 100644 --- a/dag/gunbc/scm_compatibility/pijul.dag +++ b/dag/gunbc/scm_compatibility/pijul.dag @@ -1,13 +1,40 @@ module gunbc.scm_compatibility.pijul -import std.types { NonEmptyStr } +import std.types { Bytes, ContentHash, List, NonEmptyStr, String } +import std.integer { UInt8 } +import std.bytes { bytes_octets } import v2.std.optional { Present, Absent } import extdeps.pijul { PijulUpstreamVersion, + PijulChangeHash, PijulChannelName, PijulChannelStateIdentity, + PijulChannel, PijulRepositoryProjection, PijulDecodedRepository, + PijulDecodedAvailability, + PijulDecodedComplete, + PijulDecodedPartial, + PijulRepositoryState, + PijulVertexId, + PijulGraphVertex, + PijulGraphEdge, + PijulEdgeDisposition, + PijulAliveEdge, + PijulDeletedEdge, + PijulConflictFact, + PijulConflictFactFold, + PijulTreeEntry, + PijulTreeEntryKind, + PijulDirectoryEntry, + PijulFileEntry, + PijulSymlinkEntry, + PijulWorkingCopyEntry, + PijulWorkingCopyDisposition, + PijulWorkingCopyClean, + PijulWorkingCopyModified, + PijulWorkingCopyUntracked, + PijulPath, PijulProjectionRefusal, PijulReadBackObservation, PijulReadBackMismatchAxis, @@ -21,6 +48,7 @@ import extdeps.pijul { pijul_decode_projection, pijul_assess_read_back, pijul_find_channel, + pijul_conflict_fact_fold, pijul_r0_conditional_advance, } import gunbc.scm_compatibility_shape { @@ -32,10 +60,16 @@ import gunbc.scm_compatibility_shape { CompatibilityFidelityDowngraded, CompatibilityFidelityUnavailable, CompatibilityAdvanceUnavailable, + compatibility_identity_text, + compatibility_identity_sequence, + compatibility_projection_handle, + compatibility_read_back_handle, } data pijul_compatibility_binding_note: NonEmptyStr = "The Pijul R1 handler consumes Pijul's own projection decoder, channel state identity, recorded changes, dependency/context graph, graph-conflict facts, partial availability, and independent read-back assessment. Those facts remain in PijulCompatibilityReceipt. The shared target and generation handles are opaque projections only; they are not commits, refs, branches, or semantic conflict verdicts, and R0 honestly reports conditional advance as unavailable." +data pijul_compatibility_read_back_identity_note: NonEmptyStr = "A PijulCompatibilityReceipt is constructible by this handler only after pijul_assess_read_back proves that the independently decoded observation equals repository. Its common read-back handle fingerprints the decoded repository state and availability plus the observing Pijul version; the producer version never substitutes for state identity." + type PijulCompatibilityReceipt { target: PijulChannelName generation: PijulChannelStateIdentity @@ -136,23 +170,20 @@ fn pijul_compatibility_fidelity() -> CompatibilityFidelityProfile { } } -fn pijul_compatibility_read_back_handle( +fn pijul_compatibility_version_text( version: PijulUpstreamVersion, ) -> NonEmptyStr { concat( - "pijul-readback:", + to_string(version.major), concat( - to_string(version.major), + ".", concat( - ".", + to_string(version.minor), concat( - to_string(version.minor), + ".", concat( - ".", - concat( - to_string(version.patch), - concat("-beta.", to_string(version.beta)), - ), + to_string(version.patch), + concat("-beta.", to_string(version.beta)), ), ), ), @@ -160,10 +191,469 @@ fn pijul_compatibility_read_back_handle( ) } +fn pijul_compatibility_octets_identity( + tag: NonEmptyStr, + octets: List, +) -> ContentHash { + compatibility_identity_sequence( + tag: tag, + members: octets + |> map(octet => + compatibility_identity_text( + tag: "octet", + value: to_string(octet), + ) + ), + ) +} + +fn pijul_compatibility_bytes_identity( + tag: NonEmptyStr, + bytes: Bytes, +) -> ContentHash { + pijul_compatibility_octets_identity( + tag: tag, + octets: bytes_octets(b: bytes), + ) +} + +fn pijul_compatibility_path_identity( + tag: NonEmptyStr, + path: PijulPath, +) -> ContentHash { + pijul_compatibility_octets_identity( + tag: tag, + octets: path.octets, + ) +} + +fn pijul_compatibility_vertex_identity( + tag: NonEmptyStr, + vertex: PijulVertexId, +) -> ContentHash { + compatibility_identity_sequence( + tag: tag, + members: [ + compatibility_identity_text( + tag: "introduced-by", + value: vertex.introduced_by as String, + ), + compatibility_identity_text( + tag: "position", + value: to_string(vertex.position.value), + ), + ], + ) +} + +fn pijul_compatibility_graph_vertex_identity( + vertex: PijulGraphVertex, +) -> ContentHash { + compatibility_identity_sequence( + tag: "pijul-graph-vertex", + members: [ + pijul_compatibility_vertex_identity( + tag: "id", + vertex: vertex.id, + ), + pijul_compatibility_bytes_identity( + tag: "content", + bytes: vertex.content, + ), + ], + ) +} + +fn pijul_compatibility_edge_disposition_identity( + disposition: PijulEdgeDisposition, +) -> ContentHash { + let label = match disposition { + PijulAliveEdge => "alive" + PijulDeletedEdge => "deleted" + } + compatibility_identity_text( + tag: "pijul-edge-disposition", + value: label, + ) +} + +fn pijul_compatibility_graph_edge_identity( + edge: PijulGraphEdge, +) -> ContentHash { + compatibility_identity_sequence( + tag: "pijul-graph-edge", + members: [ + pijul_compatibility_vertex_identity( + tag: "source", + vertex: edge.source, + ), + pijul_compatibility_vertex_identity( + tag: "target", + vertex: edge.target, + ), + compatibility_identity_text( + tag: "introduced-by", + value: edge.introduced_by as String, + ), + pijul_compatibility_edge_disposition_identity( + disposition: edge.disposition, + ), + ], + ) +} + +fn pijul_compatibility_change_hashes_identity( + tag: NonEmptyStr, + changes: List, +) -> ContentHash { + compatibility_identity_sequence( + tag: tag, + members: changes + |> map(change => + compatibility_identity_text( + tag: "change", + value: change as String, + ) + ), + ) +} + +fn pijul_compatibility_vertices_identity( + tag: NonEmptyStr, + vertices: List, +) -> ContentHash { + compatibility_identity_sequence( + tag: tag, + members: vertices + |> map(vertex => + pijul_compatibility_vertex_identity( + tag: "vertex", + vertex: vertex, + ) + ), + ) +} + +fn pijul_compatibility_paths_identity( + tag: NonEmptyStr, + paths: List, +) -> ContentHash { + compatibility_identity_sequence( + tag: tag, + members: paths + |> map(path => + pijul_compatibility_path_identity( + tag: "path", + path: path, + ) + ), + ) +} + +fn pijul_compatibility_conflict_identity( + conflict: PijulConflictFact, +) -> ContentHash { + pijul_conflict_fact_fold( + conflict: conflict, + fold: PijulConflictFactFold { + order: fn(left, right, at) { + compatibility_identity_sequence( + tag: "pijul-order-conflict", + members: [ + compatibility_identity_text( + tag: "left", + value: left as String, + ), + compatibility_identity_text( + tag: "right", + value: right as String, + ), + pijul_compatibility_vertex_identity( + tag: "at", + vertex: at, + ), + ], + ) + }, + cycle: fn(changes, vertices) { + compatibility_identity_sequence( + tag: "pijul-cycle-conflict", + members: [ + pijul_compatibility_change_hashes_identity( + tag: "changes", + changes: changes, + ), + pijul_compatibility_vertices_identity( + tag: "vertices", + vertices: vertices, + ), + ], + ) + }, + zombie: fn(introduced_by, vertex) { + compatibility_identity_sequence( + tag: "pijul-zombie-conflict", + members: [ + compatibility_identity_text( + tag: "introduced-by", + value: introduced_by as String, + ), + pijul_compatibility_vertex_identity( + tag: "vertex", + vertex: vertex, + ), + ], + ) + }, + name: fn(left, right, path) { + compatibility_identity_sequence( + tag: "pijul-name-conflict", + members: [ + compatibility_identity_text( + tag: "left", + value: left as String, + ), + compatibility_identity_text( + tag: "right", + value: right as String, + ), + pijul_compatibility_path_identity( + tag: "path", + path: path, + ), + ], + ) + }, + move: fn(changes, inode, paths) { + compatibility_identity_sequence( + tag: "pijul-move-conflict", + members: [ + pijul_compatibility_change_hashes_identity( + tag: "changes", + changes: changes, + ), + compatibility_identity_text( + tag: "inode", + value: inode as String, + ), + pijul_compatibility_paths_identity( + tag: "paths", + paths: paths, + ), + ], + ) + }, + }, + ) +} + +fn pijul_compatibility_tree_entry_kind_identity( + kind: PijulTreeEntryKind, +) -> ContentHash { + let label = match kind { + PijulDirectoryEntry => "directory" + PijulFileEntry => "file" + PijulSymlinkEntry => "symlink" + } + compatibility_identity_text( + tag: "pijul-tree-entry-kind", + value: label, + ) +} + +fn pijul_compatibility_tree_entry_identity( + entry: PijulTreeEntry, +) -> ContentHash { + compatibility_identity_sequence( + tag: "pijul-tree-entry", + members: [ + compatibility_identity_text( + tag: "inode", + value: entry.inode as String, + ), + pijul_compatibility_path_identity( + tag: "path", + path: entry.path, + ), + pijul_compatibility_tree_entry_kind_identity(kind: entry.kind), + compatibility_identity_text( + tag: "introduced-by", + value: entry.introduced_by as String, + ), + ], + ) +} + +fn pijul_compatibility_working_copy_disposition_identity( + disposition: PijulWorkingCopyDisposition, +) -> ContentHash { + let label = match disposition { + PijulWorkingCopyClean => "clean" + PijulWorkingCopyModified => "modified" + PijulWorkingCopyUntracked => "untracked" + } + compatibility_identity_text( + tag: "pijul-working-copy-disposition", + value: label, + ) +} + +fn pijul_compatibility_working_copy_entry_identity( + entry: PijulWorkingCopyEntry, +) -> ContentHash { + compatibility_identity_sequence( + tag: "pijul-working-copy-entry", + members: [ + pijul_compatibility_path_identity( + tag: "path", + path: entry.path, + ), + pijul_compatibility_bytes_identity( + tag: "content", + bytes: entry.content, + ), + pijul_compatibility_working_copy_disposition_identity( + disposition: entry.disposition, + ), + ], + ) +} + +fn pijul_compatibility_channel_identity( + channel: PijulChannel, +) -> ContentHash { + compatibility_identity_sequence( + tag: "pijul-channel", + members: [ + compatibility_identity_text( + tag: "name", + value: channel.name as String, + ), + compatibility_identity_text( + tag: "state", + value: channel.state_identity.state as String, + ), + pijul_compatibility_change_hashes_identity( + tag: "changes", + changes: channel.state_identity.changes + |> sort_by(change => change as String), + ), + ], + ) +} + +fn pijul_compatibility_availability_identity( + availability: PijulDecodedAvailability, +) -> ContentHash { + match availability { + PijulDecodedComplete => + compatibility_identity_sequence( + tag: "pijul-complete", + members: [], + ) + PijulDecodedPartial { + missing_changes, + missing_vertices, + missing_paths, + } => + compatibility_identity_sequence( + tag: "pijul-partial", + members: [ + pijul_compatibility_change_hashes_identity( + tag: "missing-changes", + changes: missing_changes, + ), + pijul_compatibility_vertices_identity( + tag: "missing-vertices", + vertices: missing_vertices, + ), + pijul_compatibility_paths_identity( + tag: "missing-paths", + paths: missing_paths, + ), + ], + ) + } +} + +fn pijul_compatibility_observed_state_identity( + repository: PijulDecodedRepository, +) -> ContentHash { + let state = repository.state + compatibility_identity_sequence( + tag: "pijul-readback-state-v1", + members: [ + compatibility_identity_sequence( + tag: "changes", + members: state.changes + |> map(change => + compatibility_identity_text( + tag: "change", + value: change.identity.hash as String, + ) + ), + ), + compatibility_identity_sequence( + tag: "vertices", + members: state.pristine.vertices + |> map(vertex => + pijul_compatibility_graph_vertex_identity(vertex: vertex) + ), + ), + compatibility_identity_sequence( + tag: "edges", + members: state.pristine.edges + |> map(edge => + pijul_compatibility_graph_edge_identity(edge: edge) + ), + ), + compatibility_identity_sequence( + tag: "conflicts", + members: state.pristine.conflicts + |> map(conflict => + pijul_compatibility_conflict_identity(conflict: conflict) + ), + ), + compatibility_identity_sequence( + tag: "tree", + members: state.tree.entries + |> map(entry => + pijul_compatibility_tree_entry_identity(entry: entry) + ), + ), + compatibility_identity_sequence( + tag: "working-copy", + members: state.working_copy.entries + |> map(entry => + pijul_compatibility_working_copy_entry_identity(entry: entry) + ), + ), + compatibility_identity_sequence( + tag: "channels", + members: state.channels + |> map(channel => + pijul_compatibility_channel_identity(channel: channel) + ) + |> sort_by(identity => identity as String), + ), + compatibility_identity_text( + tag: "current-channel", + value: state.current_channel as String, + ), + pijul_compatibility_availability_identity( + availability: repository.availability, + ), + ], + ) +} + fn pijul_compatibility_projection_receipt( receipt: PijulCompatibilityReceipt, ) -> CompatibilityProjectionReceipt { let generation = receipt.generation.state as NonEmptyStr + let state = pijul_compatibility_observed_state_identity( + repository: receipt.repository, + ) match receipt.advance { PijulConditionalAdvanceUnavailable { reason } => CompatibilityProjectionReceipt { @@ -171,9 +661,16 @@ fn pijul_compatibility_projection_receipt( target: receipt.target as NonEmptyStr, generation_evidence: generation, capture: CompatibilityUpstreamChangeEvidenceCaptured, - projection: concat("pijul-channel-state:", generation), - read_back: pijul_compatibility_read_back_handle( - version: receipt.read_back.pijul_version, + projection: compatibility_projection_handle( + realization: "pijul-r0", + state: state, + ), + read_back: compatibility_read_back_handle( + realization: "pijul-r0", + producer: pijul_compatibility_version_text( + version: receipt.read_back.pijul_version, + ), + state: state, ), advance: CompatibilityAdvanceUnavailable { cause: reason }, fidelity: pijul_compatibility_fidelity(), diff --git a/dag/test/claim/scm_compatibility_git_witness_test.dag b/dag/test/claim/scm_compatibility_git_witness_test.dag index 5082fc0531f..9f99909fb63 100644 --- a/dag/test/claim/scm_compatibility_git_witness_test.dag +++ b/dag/test/claim/scm_compatibility_git_witness_test.dag @@ -3,6 +3,7 @@ module test.claim.scm_compatibility_git_witness import std.types { Bool } import v2.std.live_tree { LiveTreeDisposition, SubstrateInputsOnly } import extdeps.git.object_store { + GitRepositoryState, GitR0ReadBackObservation, } import test.claim.git_upstream_model_witness { @@ -191,3 +192,51 @@ test fn witness_git_generation_derives_tree_from_commit() -> Bool { GitCompatibilityBound { receipt: _ } => false } } + +test fn witness_git_readback_identity_changes_with_observed_state() -> Bool { + let repository = git_r0_fixture_repository() + let observation = git_r0_fixture_read_back_observation() + let other_repository = GitRepositoryState { + object_format: repository.object_format, + objects: repository.objects, + unavailable: repository.unavailable, + refs: repository.refs, + index: repository.index, + worktree: [], + } + let other_observation = GitR0ReadBackObservation { + git_version: observation.git_version, + object_format: observation.object_format, + tree_oid: observation.tree_oid, + tree_entries: observation.tree_entries, + tag_oids: observation.tag_oids, + refs: observation.refs, + index: observation.index, + worktree: [], + unavailable: observation.unavailable, + } + match git_fixture_binding() { + GitCompatibilityBindingRefused { cause: _ } => false + GitCompatibilityBound { receipt: expected } => + match git_compatibility_bind( + repository: other_repository, + read_back: other_observation, + target: "refs/heads/main", + expected_generation: sha1_parent_commit, + proposed_generation: sha1_next_commit, + ) { + GitCompatibilityBindingRefused { cause: _ } => false + GitCompatibilityBound { receipt: other_state } => { + let expected_projection = git_compatibility_projection_receipt( + receipt: expected, + ) + let other_projection = git_compatibility_projection_receipt( + receipt: other_state, + ) + expected_projection.generation_evidence == other_projection.generation_evidence + && expected_projection.read_back != other_projection.read_back + && expected_projection.projection != other_projection.projection + } + } + } +} diff --git a/dag/test/claim/scm_compatibility_mercurial_witness_test.dag b/dag/test/claim/scm_compatibility_mercurial_witness_test.dag index 8e3b8f50fee..980f4eb4f50 100644 --- a/dag/test/claim/scm_compatibility_mercurial_witness_test.dag +++ b/dag/test/claim/scm_compatibility_mercurial_witness_test.dag @@ -5,9 +5,11 @@ import v2.std.live_tree { LiveTreeDisposition, SubstrateInputsOnly } import extdeps.mercurial { MercurialReadBackObservation, MercurialInaccessibleProjection, + MercurialPublishingServer, } import test.claim.mercurial_upstream_model_witness { mercurial_r0_fixture_projection, + projection_with_publishing, } import gunbc.scm_compatibility.mercurial { MercurialCompatibilityBindingOutcome, @@ -155,3 +157,35 @@ test fn witness_mercurial_unavailable_readback_refuses_binding() -> Bool { MercurialCompatibilityBound { receipt: _ } => false } } + +test fn witness_mercurial_readback_identity_changes_with_observed_state() -> Bool { + let other_projection = projection_with_publishing( + projection: mercurial_r0_fixture_projection(), + publishing: MercurialPublishingServer, + ) + match mercurial_fixture_binding() { + MercurialCompatibilityBindingRefused { cause: _ } => false + MercurialCompatibilityBound { receipt: expected } => + match mercurial_compatibility_bind( + projection: other_projection, + target: "default", + read_back: MercurialReadBackObservation { + projection: other_projection, + observed_by: "mercurial-r1-independent-fixture", + }, + ) { + MercurialCompatibilityBindingRefused { cause: _ } => false + MercurialCompatibilityBound { receipt: other_state } => { + let expected_projection = mercurial_compatibility_projection_receipt( + receipt: expected, + ) + let other_state_projection = mercurial_compatibility_projection_receipt( + receipt: other_state, + ) + expected_projection.generation_evidence == other_state_projection.generation_evidence + && expected_projection.read_back != other_state_projection.read_back + && expected_projection.projection != other_state_projection.projection + } + } + } +} diff --git a/dag/test/claim/scm_compatibility_pijul_witness_test.dag b/dag/test/claim/scm_compatibility_pijul_witness_test.dag index a213ca2b747..2e237d7d651 100644 --- a/dag/test/claim/scm_compatibility_pijul_witness_test.dag +++ b/dag/test/claim/scm_compatibility_pijul_witness_test.dag @@ -4,12 +4,17 @@ import std.types { Bool } import v2.std.live_tree { LiveTreeDisposition, SubstrateInputsOnly } import extdeps.pijul { PijulUpstreamVersion, + PijulChannel, + PijulChannelStateIdentity, PijulReadBackObservation, PijulInaccessibleProjection, pijul_upstream_version, } import test.claim.pijul_upstream_model_witness { pijul_r0_fixture_projection, + pijul_r0_fixture_repository, + pijul_state_partial, + projection_with_channels, } import gunbc.scm_compatibility.pijul { PijulCompatibilityBindingOutcome, @@ -190,3 +195,49 @@ test fn witness_pijul_unavailable_readback_refuses_binding() -> Bool { PijulCompatibilityBound { receipt: _ } => false } } + +test fn witness_pijul_readback_identity_changes_with_observed_state() -> Bool { + let repository = pijul_r0_fixture_repository() + let other_projection = projection_with_channels( + projection: pijul_r0_fixture_projection(), + channels: repository.channels + |> map(channel => + if channel.name == "main" { + PijulChannel { + name: channel.name, + state_identity: PijulChannelStateIdentity { + state: pijul_state_partial, + changes: channel.state_identity.changes, + producer: channel.state_identity.producer, + }, + } + } else { + channel + } + ), + ) + match pijul_fixture_binding() { + PijulCompatibilityBindingRefused { cause: _ } => false + PijulCompatibilityBound { receipt: expected } => + match pijul_compatibility_bind( + projection: other_projection, + target: "main", + read_back: PijulReadBackObservation { + pijul_version: pijul_upstream_version, + projection: other_projection, + }, + ) { + PijulCompatibilityBindingRefused { cause: _ } => false + PijulCompatibilityBound { receipt: other_state } => { + let expected_projection = pijul_compatibility_projection_receipt( + receipt: expected, + ) + let other_state_projection = pijul_compatibility_projection_receipt( + receipt: other_state, + ) + expected_projection.read_back != other_state_projection.read_back + && expected_projection.projection != other_state_projection.projection + } + } + } +} From d093c1c6931808e37c35caa51d997647d01f87fd Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Wed, 29 Jul 2026 17:05:59 +0000 Subject: [PATCH 21/23] Make SCM capture fidelity multi-axis --- dag/gunbc/roadmap_authority.dag | 2 +- dag/gunbc/scm_compatibility/git.dag | 2 -- dag/gunbc/scm_compatibility/mercurial.dag | 2 -- dag/gunbc/scm_compatibility/pijul.dag | 2 -- dag/gunbc/scm_compatibility_shape.dag | 20 ------------------- ..._scm_interaction_contract_witness_test.dag | 2 -- .../scm_compatibility_pijul_witness_test.dag | 2 +- .../scm_compatibility_shape_witness_test.dag | 2 -- 8 files changed, 2 insertions(+), 32 deletions(-) diff --git a/dag/gunbc/roadmap_authority.dag b/dag/gunbc/roadmap_authority.dag index 493be55e8ff..41bd68131ce 100644 --- a/dag/gunbc/roadmap_authority.dag +++ b/dag/gunbc/roadmap_authority.dag @@ -440,7 +440,7 @@ fn declared_roadmap_nodes() -> List { volume: VolumeMedium, t: fields( headline: "Extract the compatibility realization shape from three upstream receipts", - boundary: "Consume the independently executing Git, Mercurial, and Pijul R0 boundaries and extract only their demonstrated roles: opaque target/generation handles, capture class, fidelity profile, projection/read-back identity, and modeled-or-unavailable conditional-advance capability. Native receipts retain every upstream-specific fact; dispatch is a generic handler value, never ScmKind or a vendor switch.", + boundary: "Consume the independently executing Git, Mercurial, and Pijul R0 boundaries and extract only their demonstrated roles: opaque target/generation handles, an independently required fidelity disposition for each retained or lost capture axis, projection/read-back identity, and modeled-or-unavailable conditional-advance capability. Native receipts retain every upstream-specific fact; dispatch is a generic handler value, never ScmKind or a vendor switch.", displaced_cost: "Lets the native edit → submit → outcome contract project through plural SCMs without forcing users into Git mechanics or erasing Mercurial/Pijul distinctions into a first-adapter abstraction.", first_slice: "Bind each R0 fixture through its native decoder and read-back assessment, replace C0's optional Git projection slot with realization-indexed receipts, and execute one fixed C0 proposal through Git, Mercurial, Pijul, and a synthetic fourth handler.", red_control: "C0 proposal identity, transition, and primary outcome stay unchanged across all realizations; missing or differently grounded conditional advance refuses; a read-back mismatch refuses; the fourth handler requires no primary-contract or kernel edit.", diff --git a/dag/gunbc/scm_compatibility/git.dag b/dag/gunbc/scm_compatibility/git.dag index 7b4213d9aa7..eade53954ea 100644 --- a/dag/gunbc/scm_compatibility/git.dag +++ b/dag/gunbc/scm_compatibility/git.dag @@ -75,7 +75,6 @@ import gunbc.scm_compatibility_shape { CompatibilityProjectionReceipt, CompatibilityProjectionHandler, CompatibilityFidelityProfile, - CompatibilityEndpointStateCaptured, CompatibilityFidelityPreserved, CompatibilityFidelityDowngraded, CompatibilityFidelityUnavailable, @@ -728,7 +727,6 @@ fn git_compatibility_projection_receipt( realization: "git-r0", target: receipt.target as NonEmptyStr, generation_evidence: generation, - capture: CompatibilityEndpointStateCaptured, projection: compatibility_projection_handle( realization: "git-r0", state: state, diff --git a/dag/gunbc/scm_compatibility/mercurial.dag b/dag/gunbc/scm_compatibility/mercurial.dag index dedcd1b7a25..e8254b7c0dc 100644 --- a/dag/gunbc/scm_compatibility/mercurial.dag +++ b/dag/gunbc/scm_compatibility/mercurial.dag @@ -52,7 +52,6 @@ import gunbc.scm_compatibility_shape { CompatibilityProjectionReceipt, CompatibilityProjectionHandler, CompatibilityFidelityProfile, - CompatibilityEndpointStateCaptured, CompatibilityFidelityPreserved, CompatibilityFidelityDowngraded, CompatibilityFidelityUnavailable, @@ -616,7 +615,6 @@ fn mercurial_compatibility_projection_receipt( realization: "mercurial-r0", target: receipt.target as NonEmptyStr, generation_evidence: generation, - capture: CompatibilityEndpointStateCaptured, projection: compatibility_projection_handle( realization: "mercurial-r0", state: state, diff --git a/dag/gunbc/scm_compatibility/pijul.dag b/dag/gunbc/scm_compatibility/pijul.dag index a5bc25b08ee..ce7928ea510 100644 --- a/dag/gunbc/scm_compatibility/pijul.dag +++ b/dag/gunbc/scm_compatibility/pijul.dag @@ -55,7 +55,6 @@ import gunbc.scm_compatibility_shape { CompatibilityProjectionReceipt, CompatibilityProjectionHandler, CompatibilityFidelityProfile, - CompatibilityUpstreamChangeEvidenceCaptured, CompatibilityFidelityPreserved, CompatibilityFidelityDowngraded, CompatibilityFidelityUnavailable, @@ -660,7 +659,6 @@ fn pijul_compatibility_projection_receipt( realization: "pijul-r0", target: receipt.target as NonEmptyStr, generation_evidence: generation, - capture: CompatibilityUpstreamChangeEvidenceCaptured, projection: compatibility_projection_handle( realization: "pijul-r0", state: state, diff --git a/dag/gunbc/scm_compatibility_shape.dag b/dag/gunbc/scm_compatibility_shape.dag index 9709cbce503..c9cd48d930f 100644 --- a/dag/gunbc/scm_compatibility_shape.dag +++ b/dag/gunbc/scm_compatibility_shape.dag @@ -73,25 +73,6 @@ fn compatibility_read_back_handle( ) as CompatibilityReadBackHandle } -type CompatibilityCaptureClass - = CompatibilityEndpointStateCaptured - | CompatibilityUpstreamChangeEvidenceCaptured - -type CompatibilityCaptureClassFold { - endpoint_state: fn() -> R - upstream_change_evidence: fn() -> R -} - -fn compatibility_capture_class_fold( - capture: CompatibilityCaptureClass, - fold: CompatibilityCaptureClassFold, -) -> R { - match capture { - CompatibilityEndpointStateCaptured => fold.endpoint_state() - CompatibilityUpstreamChangeEvidenceCaptured => fold.upstream_change_evidence() - } -} - type CompatibilityFidelityDisposition = CompatibilityFidelityPreserved | CompatibilityFidelityDowngraded { cause: NonEmptyStr } @@ -252,7 +233,6 @@ type CompatibilityProjectionReceipt { realization: CompatibilityRealizationHandle target: CompatibilityTargetHandle generation_evidence: CompatibilityGenerationEvidenceHandle - capture: CompatibilityCaptureClass projection: CompatibilityProjectionHandle read_back: CompatibilityReadBackHandle advance: CompatibilityAdvanceCapability diff --git a/dag/test/claim/native_scm_interaction_contract_witness_test.dag b/dag/test/claim/native_scm_interaction_contract_witness_test.dag index 8749f9d95ef..a055033ee33 100644 --- a/dag/test/claim/native_scm_interaction_contract_witness_test.dag +++ b/dag/test/claim/native_scm_interaction_contract_witness_test.dag @@ -30,7 +30,6 @@ import gunbc.native_scm_interaction_contract { import gunbc.scm_compatibility_shape { CompatibilityProjectionReceipt, CompatibilityFidelityProfile, - CompatibilityEndpointStateCaptured, CompatibilityFidelityPreserved, CompatibilityFidelityUnavailable, CompatibilityAdvanceUnavailable, @@ -51,7 +50,6 @@ fn fixture_compatibility_projection() -> CompatibilityProjectionReceipt { realization: "git-r0", target: "refs/heads/main", generation_evidence: "git-generation-fixture", - capture: CompatibilityEndpointStateCaptured, projection: "git-projection-fixture", read_back: "git-readback-fixture", advance: CompatibilityAdvanceUnavailable { diff --git a/dag/test/claim/scm_compatibility_pijul_witness_test.dag b/dag/test/claim/scm_compatibility_pijul_witness_test.dag index 2e237d7d651..14dc2f94ede 100644 --- a/dag/test/claim/scm_compatibility_pijul_witness_test.dag +++ b/dag/test/claim/scm_compatibility_pijul_witness_test.dag @@ -202,7 +202,7 @@ test fn witness_pijul_readback_identity_changes_with_observed_state() -> Bool { projection: pijul_r0_fixture_projection(), channels: repository.channels |> map(channel => - if channel.name == "main" { + if channel.name == "main" || channel.name == "review" { PijulChannel { name: channel.name, state_identity: PijulChannelStateIdentity { diff --git a/dag/test/claim/scm_compatibility_shape_witness_test.dag b/dag/test/claim/scm_compatibility_shape_witness_test.dag index ad5ec7ed736..d08953b9b51 100644 --- a/dag/test/claim/scm_compatibility_shape_witness_test.dag +++ b/dag/test/claim/scm_compatibility_shape_witness_test.dag @@ -6,7 +6,6 @@ import gunbc.scm_compatibility_shape { CompatibilityProjectionReceipt, CompatibilityProjectionHandler, CompatibilityFidelityProfile, - CompatibilityEndpointStateCaptured, CompatibilityFidelityPreserved, CompatibilityFidelityUnavailable, CompatibilityAdvanceUnavailable, @@ -57,7 +56,6 @@ fn synthetic_fourth_handler( realization: "synthetic-fourth-r0", target: receipt.target, generation_evidence: receipt.generation, - capture: CompatibilityEndpointStateCaptured, projection: concat("synthetic-projection:", receipt.generation), read_back: concat("synthetic-readback:", receipt.generation), advance: CompatibilityAdvanceUnavailable { From 8d75ecb98fab8af6fa481ce6e07a1400ce839213 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Wed, 29 Jul 2026 17:34:12 +0000 Subject: [PATCH 22/23] WIP: business --- dag/gunbc/roadmap_authority.dag | 1 - dag/test/claim/roadmap_authority_test.dag | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/dag/gunbc/roadmap_authority.dag b/dag/gunbc/roadmap_authority.dag index 41bd68131ce..33d38767cfa 100644 --- a/dag/gunbc/roadmap_authority.dag +++ b/dag/gunbc/roadmap_authority.dag @@ -1263,7 +1263,6 @@ fn declared_roadmap_edges() -> List { edge(child: "2-scm-compatibility-shape", parent: "2-scm-git-upstream-model"), edge(child: "2-scm-compatibility-shape", parent: "2-scm-mercurial-upstream-model"), edge(child: "2-scm-compatibility-shape", parent: "2-scm-pijul-upstream-model"), - edge(child: "2-scm-compatibility-shape", parent: "2-claim-indexed-evidence"), edge(child: "namespace-canonical-binding", parent: "namespace-occurrence-transport"), edge(child: "namespace-bound-only-consumers", parent: "namespace-canonical-binding"), diff --git a/dag/test/claim/roadmap_authority_test.dag b/dag/test/claim/roadmap_authority_test.dag index 2fbb32d92e8..696b6418cf9 100644 --- a/dag/test/claim/roadmap_authority_test.dag +++ b/dag/test/claim/roadmap_authority_test.dag @@ -325,7 +325,7 @@ test fn witness_accepted_parent_discharges_active_dependency() -> Bool { && edge_exists(child: "2-scm-compatibility-shape", parent: "2-scm-git-upstream-model") && edge_exists(child: "2-scm-compatibility-shape", parent: "2-scm-mercurial-upstream-model") && edge_exists(child: "2-scm-compatibility-shape", parent: "2-scm-pijul-upstream-model") - && edge_exists(child: "2-scm-compatibility-shape", parent: "2-claim-indexed-evidence") + && !edge_exists(child: "2-scm-compatibility-shape", parent: "2-claim-indexed-evidence") } fn exit_line_bound_to(l: V1FinishLine, node: String) -> Bool { From bbaa1c2e46d783605e7700a5473644f11c06ce29 Mon Sep 17 00:00:00 2001 From: gunbc-ci-auto-heal Date: Wed, 29 Jul 2026 19:45:02 +0000 Subject: [PATCH 23/23] WIP: business --- dag/gunbc/native_scm_interaction_contract.dag | 98 +++++++++++++------ ..._scm_interaction_contract_witness_test.dag | 51 ++++++++-- 2 files changed, 112 insertions(+), 37 deletions(-) diff --git a/dag/gunbc/native_scm_interaction_contract.dag b/dag/gunbc/native_scm_interaction_contract.dag index 7ed83457d92..e0fbc6eef04 100644 --- a/dag/gunbc/native_scm_interaction_contract.dag +++ b/dag/gunbc/native_scm_interaction_contract.dag @@ -7,7 +7,7 @@ import gunbc.scm_compatibility_shape { compatibility_projection_upsert, } -data native_scm_interaction_contract_note: String = "Model-first contract carrier for the native SCM interaction slice. The model stays on the presentation side of the split: a proposal has a stable identity, the user-facing primary outcome is Landed | ChoiceRequired | CouldNotLand, review/access/check/operational remain orthogonal fields, workspace/target context stays optional, and compatibility projections are indexed by realization and target rather than a Git-only slot. No engine, semantic admission, transport, or CLI lives here; the witnesses exercise the contract as a black-box surface." +data native_scm_interaction_contract_note: String = "Model-first contract carrier for the native SCM interaction slice. The model stays on the presentation side of the split: a proposal has a stable identity, the user-facing primary outcome is Landed | ChoiceRequired | CouldNotLand, review/access/check/operational remain orthogonal fields, operational pending causes distinguish projection repair from unrelated internal work, workspace/target context stays optional, and compatibility projections are indexed by realization and target rather than a Git-only slot. No engine, semantic admission, transport, or CLI lives here; the witnesses exercise the contract as a black-box surface." type NativeScmProposalIdentity { name: String @@ -23,6 +23,12 @@ type NativeScmLifecycle | NativeScmLifecycleReady | NativeScmLifecycleRefused { reason: String } +type NativeScmOperationalState + = NativeScmOperationalReady + | NativeScmProjectionRepairPending + | NativeScmInternalWorkPending + | NativeScmOperationalRefused { reason: String } + type NativeScmProjection { workspace: Optional target: Optional @@ -64,12 +70,27 @@ type NativeScmReceipt { review: NativeScmLifecycle access: NativeScmLifecycle check: NativeScmLifecycle - operational: NativeScmLifecycle + operational: NativeScmOperationalState projections: NativeScmProjection primary: NativeScmPrimaryOutcome receipt_details: Optional } +type NativeScmProjectionRepairOutcome + = NativeScmProjectionRepaired { + receipt: NativeScmReceipt + } + | NativeScmProjectionRepairNotPending { + receipt: NativeScmReceipt + } + | NativeScmProjectionRepairBlockedByInternalWork { + receipt: NativeScmReceipt + } + | NativeScmProjectionRepairAlreadyRefused { + receipt: NativeScmReceipt + reason: String + } + type NativeScmSubmissionLedger { applied: List } @@ -306,19 +327,19 @@ fn native_scm_check_for(scenario: NativeScmScenario) -> NativeScmLifecycle { } } -fn native_scm_operational_for(scenario: NativeScmScenario) -> NativeScmLifecycle { +fn native_scm_operational_for(scenario: NativeScmScenario) -> NativeScmOperationalState { match scenario { - ProjectionFailureRepairsWithoutReinterpretation => NativeScmLifecyclePending - ToolModelProofDeficitRoutesInternally => NativeScmLifecyclePending - TwoIndependentChangesLand => NativeScmLifecycleReady - StaleTargetAutoResync => NativeScmLifecycleReady - DuplicateSubmissionAppliesOnce => NativeScmLifecycleReady - RenameReferenceUniqueMeaning => NativeScmLifecycleReady - TwoLegitimateMeaningsNeedChoice => NativeScmLifecycleReady - IncompatibleGoalsNeedAuthorizedDecider => NativeScmLifecycleReady - EvidenceGatheredInternally => NativeScmLifecycleReady - ConventionalScmImportWithoutManualRewrite => NativeScmLifecycleReady - VisibilityAuthorizedDetails => NativeScmLifecycleReady + ProjectionFailureRepairsWithoutReinterpretation => NativeScmProjectionRepairPending + ToolModelProofDeficitRoutesInternally => NativeScmInternalWorkPending + TwoIndependentChangesLand => NativeScmOperationalReady + StaleTargetAutoResync => NativeScmOperationalReady + DuplicateSubmissionAppliesOnce => NativeScmOperationalReady + RenameReferenceUniqueMeaning => NativeScmOperationalReady + TwoLegitimateMeaningsNeedChoice => NativeScmOperationalReady + IncompatibleGoalsNeedAuthorizedDecider => NativeScmOperationalReady + EvidenceGatheredInternally => NativeScmOperationalReady + ConventionalScmImportWithoutManualRewrite => NativeScmOperationalReady + VisibilityAuthorizedDetails => NativeScmOperationalReady } } @@ -479,21 +500,40 @@ fn native_scm_attach_projection( fn native_scm_record_repaired_projection( receipt: NativeScmReceipt, projection: CompatibilityProjectionReceipt, -) -> NativeScmReceipt { - let attached = native_scm_attach_projection( - receipt: receipt, - projection: projection, - ) - NativeScmReceipt { - identity: attached.identity, - transition: attached.transition, - review: attached.review, - access: attached.access, - check: attached.check, - operational: NativeScmLifecycleReady, - projections: attached.projections, - primary: attached.primary, - receipt_details: attached.receipt_details, +) -> NativeScmProjectionRepairOutcome { + match receipt.operational { + NativeScmProjectionRepairPending => { + let attached = native_scm_attach_projection( + receipt: receipt, + projection: projection, + ) + NativeScmProjectionRepaired { + receipt: NativeScmReceipt { + identity: attached.identity, + transition: attached.transition, + review: attached.review, + access: attached.access, + check: attached.check, + operational: NativeScmOperationalReady, + projections: attached.projections, + primary: attached.primary, + receipt_details: attached.receipt_details, + }, + } + } + NativeScmInternalWorkPending => + NativeScmProjectionRepairBlockedByInternalWork { + receipt: receipt, + } + NativeScmOperationalReady => + NativeScmProjectionRepairNotPending { + receipt: receipt, + } + NativeScmOperationalRefused { reason } => + NativeScmProjectionRepairAlreadyRefused { + receipt: receipt, + reason: reason, + } } } diff --git a/dag/test/claim/native_scm_interaction_contract_witness_test.dag b/dag/test/claim/native_scm_interaction_contract_witness_test.dag index a055033ee33..475de66c297 100644 --- a/dag/test/claim/native_scm_interaction_contract_witness_test.dag +++ b/dag/test/claim/native_scm_interaction_contract_witness_test.dag @@ -6,6 +6,11 @@ import v2.std.live_tree { LiveTreeDisposition, SubstrateInputsOnly } import gunbc.native_scm_interaction_contract { NativeScmScenario, NativeScmReceipt, + NativeScmProjectionRepaired, + NativeScmProjectionRepairBlockedByInternalWork, + NativeScmOperationalReady, + NativeScmInternalWorkPending, + NativeScmLifecyclePending, TwoIndependentChangesLand, StaleTargetAutoResync, DuplicateSubmissionAppliesOnce, @@ -203,19 +208,49 @@ test fn witness_tool_model_proof_deficits_stay_internal() -> Bool { test fn witness_projection_failure_repairs_without_reinterpretation() -> Bool { let r = receipt_for(scenario: ProjectionFailureRepairsWithoutReinterpretation) - let repaired = native_scm_record_repaired_projection( + let outcome = native_scm_record_repaired_projection( receipt: r, projection: fixture_compatibility_projection(), ) primary_label(receipt: r) == "Landed" - && primary_label(receipt: repaired) == "Landed" && count(r.projections.realizations) == 0 - && count(repaired.projections.realizations) == 1 - && repaired.projections.realizations - |> any(row => - row.realization == "git-r0" - && row.target == "refs/heads/main" - ) + && match outcome { + NativeScmProjectionRepaired { receipt: repaired } => + primary_label(receipt: repaired) == "Landed" + && count(repaired.projections.realizations) == 1 + && repaired.projections.realizations + |> any(row => + row.realization == "git-r0" + && row.target == "refs/heads/main" + ) + && match repaired.operational { + NativeScmOperationalReady => true + _ => false + } + _ => false + } +} + +test fn witness_projection_repair_cannot_clear_internal_deficit() -> Bool { + let r = receipt_for(scenario: ToolModelProofDeficitRoutesInternally) + let outcome = native_scm_record_repaired_projection( + receipt: r, + projection: fixture_compatibility_projection(), + ) + match outcome { + NativeScmProjectionRepairBlockedByInternalWork { receipt: unchanged } => + primary_label(receipt: unchanged) == "InProgress" + && count(unchanged.projections.realizations) == 0 + && match unchanged.operational { + NativeScmInternalWorkPending => true + _ => false + } + && match unchanged.check { + NativeScmLifecyclePending => true + _ => false + } + _ => false + } } test fn witness_conventional_scm_import_without_manual_rewrite() -> Bool {