Files
ss-tools/backend/tests/services/clean_release/test_demo_mode_isolation.py
busya f49b7d909e feat: GRACE-Poly protocol optimization — ~3200→10 warnings (↓99.7%)
Full optimization cycle:

Protocol (15 files):
- 4-layer SSOT architecture for agent prompts & skills
- Anti-Corruption Protocol consolidated from 5 duplicates
- Tag-to-tier permissiveness matrix (all @tags allowed at all tiers)

Axiom config:
- complexity_rules: all 22+ tags available on C1-C5
- contract_type_overrides: removed (was narrowing per-type)
- 18 new tags added, LAYER enum expanded (Infra, Frontend, Atom, etc.)
- RELATION predicates expanded (USES, CONTAINS, BELONGS_TO, etc.)

Code fixes:
- 2216 @TAG: normalized to @TAG (colon→space)
- 518 [DEF] blocks migrated to #region/#endregion (37 files)
- VERIFIES→BINDS_TO, :Class/:Function suffixes removed, paths→IDs
- 1173-line _external_stubs.py deleted (EXT: handled natively)
- Batch EXT: reference audit (240 targets: 132 external, 99 internal, 9 fix)
- QA regression check: 0 regressions across all checks

Infrastructure:
- DuckDB rebuild stabilized (appender API, INSERT OR IGNORE)
- Anchor regex fix (parent-child BINDS_TO now resolves)
- EXT:*/DTO:/NEED_CONTEXT: regex fixed in validator
- 34MB Doxygen API portal (3194 contract pages)
2026-05-26 11:14:25 +03:00

90 lines
3.6 KiB
Python

# #region TestDemoModeIsolation [C:2] [TYPE Module]
# @SEMANTICS: clean-release, demo-mode, isolation, namespace, repository
# @PURPOSE: Verify demo and real mode namespace isolation contracts before TUI integration.
# @LAYER Tests
# @RELATION DEPENDS_ON -> [DemoDataService]
from __future__ import annotations
from datetime import UTC, datetime
from src.models.clean_release import ReleaseCandidate
from src.services.clean_release.demo_data_service import (
build_namespaced_id,
create_isolated_repository,
resolve_namespace,
)
# #region test_resolve_namespace_separates_demo_and_real [C:2] [TYPE Function]
# @RELATION BINDS_TO -> TestDemoModeIsolation
# @PURPOSE: Ensure namespace resolver returns deterministic and distinct namespaces.
# @PRE: Mode names are provided as user/runtime strings.
# @POST: Demo and real namespaces are different and stable.
def test_resolve_namespace_separates_demo_and_real() -> None:
demo = resolve_namespace("demo")
real = resolve_namespace("real")
assert demo == "clean-release:demo"
assert real == "clean-release:real"
assert demo != real
# #endregion test_resolve_namespace_separates_demo_and_real
# #region test_build_namespaced_id_prevents_cross_mode_collisions [C:2] [TYPE Function]
# @RELATION BINDS_TO -> TestDemoModeIsolation
# @PURPOSE: Ensure ID generation prevents demo/real collisions for identical logical IDs.
# @PRE: Same logical candidate id is used in two different namespaces.
# @POST: Produced physical IDs differ by namespace prefix.
def test_build_namespaced_id_prevents_cross_mode_collisions() -> None:
logical_id = "2026.03.09-rc1"
demo_id = build_namespaced_id(resolve_namespace("demo"), logical_id)
real_id = build_namespaced_id(resolve_namespace("real"), logical_id)
assert demo_id != real_id
assert demo_id.startswith("clean-release:demo::")
assert real_id.startswith("clean-release:real::")
# #endregion test_build_namespaced_id_prevents_cross_mode_collisions
# #region test_create_isolated_repository_keeps_mode_data_separate [C:2] [TYPE Function]
# @RELATION BINDS_TO -> TestDemoModeIsolation
# @PURPOSE: Verify demo and real repositories do not leak state across mode boundaries.
# @PRE: Two repositories are created for distinct modes.
# @POST: Candidate mutations in one mode are not visible in the other mode.
def test_create_isolated_repository_keeps_mode_data_separate() -> None:
demo_repo = create_isolated_repository("demo")
real_repo = create_isolated_repository("real")
demo_candidate_id = build_namespaced_id(resolve_namespace("demo"), "candidate-1")
real_candidate_id = build_namespaced_id(resolve_namespace("real"), "candidate-1")
demo_repo.save_candidate(
ReleaseCandidate(
id=demo_candidate_id,
version="1.0.0",
source_snapshot_ref="git:sha-demo",
created_by="demo-operator",
created_at=datetime.now(UTC),
status="DRAFT",
)
)
real_repo.save_candidate(
ReleaseCandidate(
id=real_candidate_id,
version="1.0.0",
source_snapshot_ref="git:sha-real",
created_by="real-operator",
created_at=datetime.now(UTC),
status="DRAFT",
)
)
assert demo_repo.get_candidate(demo_candidate_id) is not None
assert demo_repo.get_candidate(real_candidate_id) is None
assert real_repo.get_candidate(real_candidate_id) is not None
assert real_repo.get_candidate(demo_candidate_id) is None
# #endregion test_create_isolated_repository_keeps_mode_data_separate
# #endregion TestDemoModeIsolation