Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions loopx/capabilities/context_providers/service_ownership.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@

import hashlib
import json
import re
from dataclasses import dataclass
from pathlib import Path
from typing import Mapping

from ...file_lock import process_is_alive
from ...public_safe_text import COMPACT_LABEL_PATTERN as _LABEL


CONTEXT_PROVIDER_SERVICE_RECEIPT_SCHEMA_VERSION = (
Expand All @@ -22,7 +22,6 @@
"pid",
"observed_at",
}
_LABEL = re.compile(r"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,119}$")


def _opaque_ref(kind: str, value: str) -> str:
Expand Down
2 changes: 1 addition & 1 deletion loopx/capabilities/issue_fix/repository_context.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from urllib.parse import urlsplit

from ...control_plane.runtime.public_safety import public_safe_compact_text
from ...public_safe_text import COMPACT_LABEL_PATTERN as _SOURCE_ID_PATTERN
from .repository_memory import (
SUPPORT_ASPECTS,
build_issue_fix_repository_memory_hook,
Expand Down Expand Up @@ -36,7 +37,6 @@
REQUIRED_FIX_ASPECTS = ("change_scope", "reproduction", "validation")
MAX_SOURCES = 16

_SOURCE_ID_PATTERN = re.compile(r"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,119}$")
_INPUT_FIELDS = {"schema_version", "repository_revision", "sources"}
_SOURCE_FIELDS = {
"source_id",
Expand Down
2 changes: 1 addition & 1 deletion loopx/capabilities/issue_fix/repository_memory.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from typing import Any

from ...control_plane.runtime.public_safety import public_safe_compact_text
from ...public_safe_text import COMPACT_LABEL_PATTERN as _LABEL_PATTERN


ISSUE_FIX_REPOSITORY_MEMORY_READ_RESULT_SCHEMA_VERSION = (
Expand All @@ -31,7 +32,6 @@
}
MAX_MEMORY_RESULTS = 6

_LABEL_PATTERN = re.compile(r"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,119}$")
_INPUT_FIELDS = {
"schema_version",
"provider",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
)
from ...repository_identity import resolve_project_identity
from ...control_plane.runtime.public_safety import public_safe_compact_text
from ...public_safe_text import COMPACT_LABEL_PATTERN as _LABEL
from .repository_memory import (
ISSUE_FIX_REPOSITORY_MEMORY_READ_RESULT_SCHEMA_VERSION,
MAX_MEMORY_RESULTS,
Expand Down Expand Up @@ -66,7 +67,6 @@
"active_repository_revision",
"active_scope_ref",
}
_LABEL = re.compile(r"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,119}$")
_FORBIDDEN_WRITEBACK_FIELDS = {
"credential",
"credentials",
Expand Down
2 changes: 1 addition & 1 deletion loopx/capabilities/issue_fix/reviewer_recommendation.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
from urllib.parse import urlsplit

from ...control_plane.runtime.public_safety import public_safe_compact_text
from ...public_safe_text import COMPACT_LABEL_PATTERN as REVIEWER_SOURCE_ID_PATTERN


ISSUE_FIX_REVIEWER_RECOMMENDATION_SCHEMA_VERSION = (
Expand Down Expand Up @@ -43,7 +44,6 @@
"path_glob",
"repository_fallback",
}
REVIEWER_SOURCE_ID_PATTERN = re.compile(r"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,119}$")
REVIEWER_SOURCE_INPUT_FIELDS = {"schema_version", "sources"}
REVIEWER_SOURCE_FIELDS = {
"source_id",
Expand Down
2 changes: 1 addition & 1 deletion loopx/capabilities/reliability_diagnostics/envelope.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,14 @@
normalize_public_safe_field_name,
validate_public_safe_value,
)
from ...public_safe_text import IDENTITY_TOKEN_PATTERN
from ...session_runtime import SOURCE_ID_KEYS

CAPABILITY_ID = "reliability-diagnostics"
DSH_PROVIDER_ID = "dsh-session-events"
OBSERVER_ENVELOPE_SCHEMA_VERSION = "reliability_observer_envelope_v0"
OBSERVER_STATS_SCHEMA_VERSION = "reliability_observer_stats_v0"

IDENTITY_TOKEN_PATTERN = re.compile(r"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,120}$")
SUMMARY_TOKEN_PATTERN = re.compile(r"^[A-Za-z0-9][A-Za-z0-9_./:-]{0,79}$")
MAX_SEQUENCE = 2**53

Expand Down
4 changes: 1 addition & 3 deletions loopx/control_plane/runtime/public_safety.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
# --no-implicit-reexport), so the existing importers of these names from this
# module are unchanged.
from ...public_safe_text import (
IDENTITY_TOKEN_PATTERN as LOOPX_COMMAND_RECORD_GOAL_ID_PATTERN,
LOCAL_PATH_SURFACE_PATTERN as LOCAL_PATH_SURFACE_PATTERN,
PUBLIC_SAFE_LOCAL_PATH_PATTERNS as PUBLIC_SAFE_LOCAL_PATH_PATTERNS,
REMOTE_LOCATION_SURFACE_PATTERN as REMOTE_LOCATION_SURFACE_PATTERN,
Expand Down Expand Up @@ -54,9 +55,6 @@
"diagnose",
}
LOOPX_COMMAND_RECORD_TODO_ID_PATTERN = re.compile(r"^todo_[A-Za-z0-9_-]{6,80}$")
LOOPX_COMMAND_RECORD_GOAL_ID_PATTERN = re.compile(
r"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,120}$"
)


def compact_text(text: str, *, limit: int) -> str:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
from ...control_plane.runtime.public_safety import public_safe_compact_text
from ...entrypoint import pin_utf8_stdio
from ...history import collect_history, validate_goal_id_path_segment
from ...public_safe_text import IDENTITY_TOKEN_PATTERN as _PUBLIC_GOAL_ID_RE

HISTORY_EXPORT_SCHEMA_VERSION = "loopx_history_conclusion_export_v0"

Expand All @@ -44,7 +45,6 @@
_SLUG_RE = re.compile(r"[^A-Za-z0-9._-]+")
# Bounded ISO-8601-ish timestamp: digits, T/space, colon, dot, +/- and Z only.
_TIMESTAMP_RE = re.compile(r"^[0-9]{4}-[0-9]{2}-[0-9]{2}[T ][0-9:.+\-]{1,20}Z?$")
_PUBLIC_GOAL_ID_RE = re.compile(r"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,120}$")
_SECRET_SHAPED_GOAL_ID_RE = re.compile(
r"(?i)^(?:"
r"gh[pousr]_[A-Za-z0-9]{20,}|"
Expand Down
15 changes: 15 additions & 0 deletions loopx/public_safe_text.py
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,21 @@
# a value this shape accepts is not yet a claim that the destination may publish
# it.
OPAQUE_ID_PATTERN = re.compile(r"^[A-Za-z0-9._:-]{1,200}$")
# One definition for "a compact label naming a provider, service or source". Five
# contracts each compiled this body under their own name -- the service-ownership
# projection, the Issue-Fix repository context and repository memory, the memory
# provider that publishes them, and the reviewer-recommendation route -- and each
# keeps its own field names and error text. The bound is the one those sites
# already enforced: widening it to the 120-character identity shape below would
# accept labels they reject today, so the two stay separate on purpose and
# tests/control_plane/test_compact_identifier_shape_owner.py census both.
COMPACT_LABEL_PATTERN = re.compile(r"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,119}$")
# One definition for "an identity token in a public-safe envelope", the shape
# `loopx/capabilities/reliability_diagnostics/README.md` already documents for
# `goal_id` and `session_id`. Three contracts compiled it locally -- the observer
# envelope, the command-record projector and the OpenViking history export -- and
# the envelope module remains the public name its own package imports.
IDENTITY_TOKEN_PATTERN = re.compile(r"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,120}$")
MODULE_QUALIFIED_SURFACE_PATTERN = re.compile(
r"^[a-z][a-z0-9_-]*(?:\.[a-z][a-z0-9_-]*)+$"
)
Expand Down
70 changes: 70 additions & 0 deletions tests/control_plane/test_compact_identifier_shape_owner.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,16 @@

from loopx import chat_action_normalization, chat_actions, chat_action_store, domain_state
from loopx.capabilities.benchmark_toolkit import integrity
from loopx.capabilities.context_providers import service_ownership
from loopx.capabilities.decision_context import packets, profile, sources
from loopx.capabilities.issue_fix import (
repository_context,
repository_memory,
repository_memory_provider,
reviewer_recommendation,
)
from loopx.capabilities.material_lifecycle import _validation
from loopx.capabilities.reliability_diagnostics import envelope
from loopx.capabilities.reward_memory import (
application,
candidate_review,
Expand All @@ -20,15 +28,19 @@
registry,
)
from loopx.capabilities.semantic_preference import contract
from loopx.control_plane.runtime import public_safety
from loopx.domain_packs import ml_experiment
from loopx.control_plane.goals import (
botmux_runtime,
deletion_service,
goal_ref_validation,
)
from loopx.extensions import presentation
from loopx.extensions.openviking_semantic_preference import history_export
from loopx.public_safe_text import (
COMPACT_LABEL_PATTERN,
COMPACT_TOKEN_PATTERN,
IDENTITY_TOKEN_PATTERN,
LETTER_LED_COMPACT_TOKEN_PATTERN,
OPAQUE_ID_PATTERN as PUBLIC_OPAQUE_ID,
MODULE_QUALIFIED_SURFACE_PATTERN,
Expand All @@ -40,6 +52,8 @@
REFERENCE_SHAPE = "^[A-Za-z0-9][A-Za-z0-9._:/#-]{0,199}$"
COMPACT_SHAPE = "^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"
LETTER_LED_SHAPE = "^[A-Za-z][A-Za-z0-9_.:-]{0,79}$"
LABEL_SHAPE = "^[A-Za-z0-9][A-Za-z0-9_.:-]{0,119}$"
IDENTITY_SHAPE = "^[A-Za-z0-9][A-Za-z0-9_.:-]{0,120}$"
SURFACE_SHAPE = "^[a-z][a-z0-9_-]*(?:\\.[a-z][a-z0-9_-]*)+$"
OPAQUE_SHAPE = "^[A-Za-z0-9._:-]{1,200}$"

Expand All @@ -49,6 +63,8 @@
OPEN_OPAQUE_SITES: dict[str, int] = {}
OPEN_COMPACT_SITES: dict[str, int] = {}
OPEN_LETTER_LED_SITES: dict[str, int] = {}
OPEN_LABEL_SITES: dict[str, int] = {}
OPEN_IDENTITY_SITES: dict[str, int] = {}


SHAPE_CONSUMERS = {
Expand All @@ -70,6 +86,18 @@
"loopx/capabilities/material_lifecycle/_validation.py",
"loopx/extensions/presentation.py",
),
LABEL_SHAPE: (
"loopx/capabilities/context_providers/service_ownership.py",
"loopx/capabilities/issue_fix/repository_context.py",
"loopx/capabilities/issue_fix/repository_memory.py",
"loopx/capabilities/issue_fix/repository_memory_provider.py",
"loopx/capabilities/issue_fix/reviewer_recommendation.py",
),
IDENTITY_SHAPE: (
"loopx/capabilities/reliability_diagnostics/envelope.py",
"loopx/control_plane/runtime/public_safety.py",
"loopx/extensions/openviking_semantic_preference/history_export.py",
),
SURFACE_SHAPE: (
"loopx/capabilities/reward_memory/application.py",
"loopx/capabilities/reward_memory/candidate_review.py",
Expand Down Expand Up @@ -144,6 +172,48 @@ def test_domain_state_and_ml_experiment_share_the_letter_led_token_shape() -> No
assert ml_experiment._TOKEN_RE is LETTER_LED_COMPACT_TOKEN_PATTERN


def test_the_label_body_is_compiled_only_by_the_owner_and_declared_sites() -> None:
found: dict[str, int] = {}
for path in sorted(REPOSITORY_ROOT.glob("loopx/**/*.py")):
relative = path.relative_to(REPOSITORY_ROOT).as_posix()
count = path.read_text(encoding="utf-8").count(LABEL_SHAPE)
if count:
found[relative] = count
assert found == {OWNER_MODULE: 1, **OPEN_LABEL_SITES}


def test_the_identity_body_is_compiled_only_by_the_owner_and_declared_sites() -> None:
found: dict[str, int] = {}
for path in sorted(REPOSITORY_ROOT.glob("loopx/**/*.py")):
relative = path.relative_to(REPOSITORY_ROOT).as_posix()
count = path.read_text(encoding="utf-8").count(IDENTITY_SHAPE)
if count:
found[relative] = count
assert found == {OWNER_MODULE: 1, **OPEN_IDENTITY_SITES}


def test_labels_and_identities_import_the_owners_object() -> None:
assert service_ownership._LABEL is COMPACT_LABEL_PATTERN
assert repository_context._SOURCE_ID_PATTERN is COMPACT_LABEL_PATTERN
assert repository_memory._LABEL_PATTERN is COMPACT_LABEL_PATTERN
assert repository_memory_provider._LABEL is COMPACT_LABEL_PATTERN
assert reviewer_recommendation.REVIEWER_SOURCE_ID_PATTERN is COMPACT_LABEL_PATTERN
assert envelope.IDENTITY_TOKEN_PATTERN is IDENTITY_TOKEN_PATTERN
assert public_safety.LOOPX_COMMAND_RECORD_GOAL_ID_PATTERN is IDENTITY_TOKEN_PATTERN
assert history_export._PUBLIC_GOAL_ID_RE is IDENTITY_TOKEN_PATTERN


def test_the_label_and_identity_bounds_stay_one_character_apart() -> None:
# These two shapes share their grammar and differ only in the bound each
# consumer already enforced, so a fold that merges them would silently widen
# one side. The pair of values that separates them is pinned here.
longest_label = "a" + "b" * 119
one_character_longer = "a" + "b" * 120
assert COMPACT_LABEL_PATTERN.fullmatch(longest_label)
assert COMPACT_LABEL_PATTERN.fullmatch(one_character_longer) is None
assert IDENTITY_TOKEN_PATTERN.fullmatch(one_character_longer)


def test_each_contract_holds_the_owners_object_and_reports_its_own_field() -> None:
assert chat_actions._OPAQUE_ID is PUBLIC_OPAQUE_ID
assert chat_action_store._OPAQUE_ID is PUBLIC_OPAQUE_ID
Expand Down