# ============================================================
# src/accountable_record/stage_070_resolution/base/constants.py
# ============================================================
"""Resolution-stage constants and diagnostic codes (Layer 0).

WHY:
    Stage 070 validates resolution and lock material for a target Accountable
    Record repository. This module is the stage's Layer 0 vocabulary: the
    AR.RS.* diagnostic codes plus the structural constants naming the lock
    root, lock file, manifest opt-out, and minimal observed lock-file shape.

OBS (boundary):
    s070 owns resolution/lock validation. It does not validate authored element
    quartets (s040), build the catalog (s050), validate export artifacts (s060),
    validate generated artifact freshness (s080), or validate documentation
    (s090).

OBS (lock scope):
    The observed AR lock file is data/locks/elements.lock.json. It records
    resolved packages and elements, including compact identifiers, versions,
    digest algorithms, digest targets, and digests. Digest recomputation is not
    assumed here; this base layer only names the structural vocabulary.

OBS (implementation-repo opt-out):
    Implementation repositories such as accountable-record-py may not carry
    target-repository lock material. Absence is allowed only when explicitly
    declared by manifest opt-out, mirroring earlier opt-out patterns such as
    [elements].declarations = "none" and [exports].artifacts = "none".

OBS (data-driven):
    No hardcoded package ids, element ids, versions, category names, or counts.
    Resolution records are read from the lock file at runtime.
"""

STAGE_NAME = "stage_070_resolution"

# Default lock location for target repositories.
LOCKS_DIRNAME = "data/locks"
ELEMENTS_LOCK_FILENAME = "elements.lock.json"
ELEMENTS_LOCK_PATH = f"{LOCKS_DIRNAME}/{ELEMENTS_LOCK_FILENAME}"

# Observed lock schema tag.
ELEMENT_LOCK_SCHEMA_TAG = "ar-element-lock-1"

# Manifest opt-out, analogous to [exports].artifacts = "none".
MANIFEST_RESOLUTION_TABLE = "resolution"
MANIFEST_LOCKS_KEY = "locks"
LOCKS_NONE = "none"

# Top-level lock keys.
LOCK_KEY_SCHEMA = "schema"
LOCK_KEY_RESOLVED_AT = "resolved_at"
LOCK_KEY_RESOLUTION_POLICY = "resolution_policy"
LOCK_KEY_PACKAGES = "packages"
LOCK_KEY_ELEMENTS = "elements"

LOCK_REQUIRED_KEYS: tuple[str, ...] = (
    LOCK_KEY_SCHEMA,
    LOCK_KEY_RESOLVED_AT,
    LOCK_KEY_RESOLUTION_POLICY,
    LOCK_KEY_PACKAGES,
    LOCK_KEY_ELEMENTS,
)

# Resolution policy keys observed in the lock.
POLICY_ONE_MAJOR_VERSION_PER_IDENTITY_PER_GRAPH = (
    "one_major_version_per_identity_per_graph"
)
POLICY_RANGE_CONFLICTS_ARE_ERRORS = "range_conflicts_are_errors"

POLICY_REQUIRED_KEYS: tuple[str, ...] = (
    POLICY_ONE_MAJOR_VERSION_PER_IDENTITY_PER_GRAPH,
    POLICY_RANGE_CONFLICTS_ARE_ERRORS,
)

# Package record keys observed in data/locks/elements.lock.json.
PACKAGE_KEY_COMPACT_ID = "compact_id"
PACKAGE_KEY_VERSION = "version"
PACKAGE_KEY_CANONICAL_URI = "canonical_uri"
PACKAGE_KEY_DIGEST_ALGORITHM = "digest_algorithm"
PACKAGE_KEY_DIGEST_TARGET = "digest_target"
PACKAGE_KEY_DIGEST = "digest"
PACKAGE_KEY_SOURCE = "source"

PACKAGE_REQUIRED_KEYS: tuple[str, ...] = (
    PACKAGE_KEY_COMPACT_ID,
    PACKAGE_KEY_VERSION,
    PACKAGE_KEY_CANONICAL_URI,
    PACKAGE_KEY_DIGEST_ALGORITHM,
    PACKAGE_KEY_DIGEST_TARGET,
    PACKAGE_KEY_DIGEST,
    PACKAGE_KEY_SOURCE,
)

# Element lock record keys observed in data/locks/elements.lock.json.
ELEMENT_KEY_COMPACT_ID = "compact_id"
ELEMENT_KEY_VERSION = "version"
ELEMENT_KEY_INCLUDED_BY = "included_by"
ELEMENT_KEY_DIGEST_ALGORITHM = "digest_algorithm"
ELEMENT_KEY_DIGEST_TARGET = "digest_target"
ELEMENT_KEY_DIGEST = "digest"

ELEMENT_REQUIRED_KEYS: tuple[str, ...] = (
    ELEMENT_KEY_COMPACT_ID,
    ELEMENT_KEY_VERSION,
    ELEMENT_KEY_INCLUDED_BY,
    ELEMENT_KEY_DIGEST_ALGORITHM,
    ELEMENT_KEY_DIGEST_TARGET,
    ELEMENT_KEY_DIGEST,
)

# Observed digest values.
DIGEST_ALGORITHM_SHA256 = "sha256"
DIGEST_TARGET_CANONICAL_GENERATED_JSON = "canonical-generated-json"
