diff --git a/examples/community-space-brand/constitution.json b/examples/community-space-brand/constitution.json index b58d6a9..b337091 100644 --- a/examples/community-space-brand/constitution.json +++ b/examples/community-space-brand/constitution.json @@ -95,6 +95,14 @@ "principle": "principle_habitability", "severity_on_violation": "high", "action_on_violation": "revise_response" + }, + { + "id": "constraint_continuity_over_one_off_activation", + "constraint_type": "soft", + "rule": "Activation should support return, trust, and relationship depth rather than isolated consumption.", + "principle": "principle_living_community", + "severity_on_violation": "medium", + "action_on_violation": "escalate_to_community_guardian" } ], "stakeholders": [ @@ -151,7 +159,12 @@ "example_purpose": "Real community space brand governance derived from co-design and Specula Method Brand Archeology", "fictional_example": false, "client": "Il posto delle fragole — Via Ponchielli 81, Pesaro", - "method_phases_applied": ["1.5", "2", "3_partial", "4"], + "method_phases_applied": [ + "1.5", + "2", + "3_partial", + "4" + ], "attribution": "Specula Future Crafting" } } diff --git a/examples/community-space-brand/state-machine.json b/examples/community-space-brand/state-machine.json index ab835ba..e590394 100644 --- a/examples/community-space-brand/state-machine.json +++ b/examples/community-space-brand/state-machine.json @@ -234,7 +234,9 @@ "applies_at_state": "generate_response", "condition": "response_supports_continuity_or_relationship_depth", "principle": "principle_living_community", - "constraint_ids": [], + "constraint_ids": [ + "constraint_continuity_over_one_off_activation" + ], "action_on_violation": "escalate", "severity": "medium", "error_message": "The response must support continuity, trust, or relationship depth rather than one-off consumption." @@ -279,9 +281,9 @@ "color_weight": { "sand": 0.5, "white": 0.15, - "green": 0.15, + "green": 0.2, "black": 0.1, - "red": 0.1 + "red": 0.05 } } }, diff --git a/tests/test_semantic_coverage.py b/tests/test_semantic_coverage.py index 0f469d8..c6934f3 100644 --- a/tests/test_semantic_coverage.py +++ b/tests/test_semantic_coverage.py @@ -86,3 +86,25 @@ def test_habitability_guards_are_attached_to_runtime_flow(): def test_real_examples_exist(): # Guard against silently testing nothing if the metadata flag changes. assert REAL_EXAMPLES, "no real (non-fictional) examples found to test" + + +# Hard constraint (constraint_activation_color_ratio): red activation <= 5%. +MAX_RED_ACTIVATION_RATIO = 0.05 + + +@pytest.mark.parametrize("example_dir", REAL_EXAMPLES, ids=lambda p: p.name) +def test_activation_color_ratio_respected_in_space_states(example_dir): + """Every real example must obey the hard constraint that + guard_activation_color_ratio enforces: red (activation) never exceeds 5% + in any declared space state. Generic across real examples so a future + over-threshold configuration fails CI, not just the current one.""" + sm = json.loads((example_dir / "state-machine.json").read_text(encoding="utf-8")) + space_states = sm.get("space_states", {}) + if not space_states: + pytest.skip(f"{example_dir.name} declares no space_states") + offenders = { + name: cfg.get("color_weight", {}).get("red", 0.0) + for name, cfg in space_states.items() + if cfg.get("color_weight", {}).get("red", 0.0) > MAX_RED_ACTIVATION_RATIO + } + assert not offenders, f"{example_dir.name} space states exceeding 5% red: {offenders}"