fix(knowledge-fs): persist greenfield audit anchor

This commit is contained in:
Jyong 2026-07-28 06:08:21 -04:00
parent 0ed37b82d3
commit 79a681b88b
2 changed files with 62 additions and 8 deletions

View File

@ -2236,17 +2236,48 @@ class KnowledgeFSWorkspaceCutoverService:
return _ActivationAnchor(control_space.id, False)
greenfield_anchor = _greenfield_activation_anchor_id(tenant_id)
has_local_control_space = session.scalar(
sa.select(sa.literal(True))
greenfield_provisioning_key = _greenfield_activation_provisioning_key(tenant_id)
local_control_space_count = session.scalar(
sa.select(sa.func.count())
.select_from(KnowledgeFSControlSpace)
.where(KnowledgeFSControlSpace.tenant_id == tenant_id)
.limit(1)
)
if (
not has_local_control_space
and _is_zero_space_cutover_ledger(ledger)
and control_space_id in {None, greenfield_anchor}
):
if not _is_zero_space_cutover_ledger(ledger) or control_space_id not in {None, greenfield_anchor}:
raise KnowledgeFSCutoverGateBlockedError(
"A tenant-owned active control-space is required for activation audit"
)
persisted_anchor = session.scalar(
sa.select(KnowledgeFSControlSpace).where(
KnowledgeFSControlSpace.tenant_id == tenant_id,
KnowledgeFSControlSpace.id == greenfield_anchor,
)
)
if persisted_anchor is not None:
if (
local_control_space_count == 1
and persisted_anchor.state is KnowledgeFSControlSpaceState.DELETED
and persisted_anchor.knowledge_space_id is None
and persisted_anchor.provisioning_key == greenfield_provisioning_key
and persisted_anchor.owner_account_id == ledger.shadow_completed_by_account_id
and persisted_anchor.lifecycle_operation_id == greenfield_anchor
):
return _ActivationAnchor(greenfield_anchor, True)
raise KnowledgeFSCutoverGateBlockedError(
"KnowledgeFS greenfield activation audit anchor conflicts with local control-space state"
)
if local_control_space_count == 0 and ledger.shadow_completed_by_account_id is not None:
persisted_anchor = KnowledgeFSControlSpace(
tenant_id=tenant_id,
owner_account_id=ledger.shadow_completed_by_account_id,
provisioning_key=greenfield_provisioning_key,
state=KnowledgeFSControlSpaceState.DELETED,
lifecycle_operation_id=greenfield_anchor,
)
persisted_anchor.id = greenfield_anchor
session.add(persisted_anchor)
session.flush()
return _ActivationAnchor(greenfield_anchor, True)
raise KnowledgeFSCutoverGateBlockedError("A tenant-owned active control-space is required for activation audit")
@ -2364,6 +2395,10 @@ def _greenfield_activation_anchor_id(tenant_id: str) -> str:
return str(uuid5(NAMESPACE_URL, f"dify-kfs-greenfield-activation:{tenant_id}"))
def _greenfield_activation_provisioning_key(tenant_id: str) -> str:
return f"dify-kfs-greenfield-activation:{tenant_id}"
def _is_zero_space_cutover_ledger(ledger: KnowledgeFSWorkspaceCutoverLedger) -> bool:
return bool(
ledger.source_revision_watermark == _ZERO_REVISION_WATERMARK

View File

@ -464,6 +464,19 @@ def test_empty_workspace_uses_a_stable_greenfield_anchor_for_remote_freeze_and_a
assert UUID(remote.freeze_requests[0].control_space_id)
assert ledger.phase is KnowledgeFSWorkspaceCutoverPhase.CUTOVER
assert ledger.product_routes_enabled is True
with session_maker() as session:
audit_anchor = session.scalar(
sa.select(KnowledgeFSControlSpace).where(
KnowledgeFSControlSpace.tenant_id == tenant_id,
KnowledgeFSControlSpace.id == remote.freeze_requests[0].control_space_id,
)
)
assert audit_anchor is not None
assert audit_anchor.state is KnowledgeFSControlSpaceState.DELETED
assert audit_anchor.knowledge_space_id is None
assert audit_anchor.owner_account_id == str(
service.status(tenant_id=tenant_id)["shadow_completed_by_account_id"]
)
def test_empty_workspace_freeze_rejects_a_nonempty_remote_namespace(
@ -506,6 +519,12 @@ def test_empty_workspace_freeze_rejects_a_nonempty_remote_namespace(
freeze_at=_BASE_TIME + timedelta(minutes=1),
)
assert remote.freeze_requests == []
with session_maker() as session:
audit_anchor = session.scalar(
sa.select(KnowledgeFSControlSpace).where(KnowledgeFSControlSpace.tenant_id == tenant_id)
)
assert audit_anchor is not None
assert audit_anchor.state is KnowledgeFSControlSpaceState.DELETED
def _quarantine_resolution(