core-runtime-engine 11.5.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (96) hide show
  1. core_runtime/__init__.py +10 -0
  2. core_runtime/__version__.py +17 -0
  3. core_runtime/cli/__init__.py +7 -0
  4. core_runtime/cli/__main__.py +22 -0
  5. core_runtime/cli/bump_version.py +176 -0
  6. core_runtime/cli/contract_preflight.py +69 -0
  7. core_runtime/cli/create_domain.py +66 -0
  8. core_runtime/cli/doctor.py +44 -0
  9. core_runtime/cli/inventory.py +85 -0
  10. core_runtime/cli/lint.py +8 -0
  11. core_runtime/cli/main.py +579 -0
  12. core_runtime/cli/release_check.py +65 -0
  13. core_runtime/cli/repair_artifact_paths.py +48 -0
  14. core_runtime/cli/sync_template.py +67 -0
  15. core_runtime/cli/validate.py +73 -0
  16. core_runtime/core/__init__.py +34 -0
  17. core_runtime/core/audit_event.py +760 -0
  18. core_runtime/core/audit_trail_index.py +100 -0
  19. core_runtime/core/canonicalization.py +55 -0
  20. core_runtime/core/contract_evaluator.py +945 -0
  21. core_runtime/core/contract_executability.py +307 -0
  22. core_runtime/core/contract_loader.py +57 -0
  23. core_runtime/core/contract_probes.py +630 -0
  24. core_runtime/core/contract_program.py +131 -0
  25. core_runtime/core/contract_program_registry.py +104 -0
  26. core_runtime/core/contract_program_v2.py +126 -0
  27. core_runtime/core/dsk_v3.py +142 -0
  28. core_runtime/core/explainability.py +2115 -0
  29. core_runtime/core/numeric_normalization.py +120 -0
  30. core_runtime/core/rule_anchor.py +1388 -0
  31. core_runtime/core/schema_fingerprint.py +69 -0
  32. core_runtime/core/sensor_evidence.py +548 -0
  33. core_runtime/data/contracts/CoreAnchor.sol +109 -0
  34. core_runtime/data/contracts/CoreRuleAnchor.abi.json +111 -0
  35. core_runtime/data/contracts/CoreRuleAnchor.bin +1 -0
  36. core_runtime/data/contracts/CoreRuleAnchor.build.json +20 -0
  37. core_runtime/data/contracts/CoreRuleAnchor.runtime.bin +1 -0
  38. core_runtime/data/contracts/CoreRuleAnchor.sol +74 -0
  39. core_runtime/data/package_data_manifest.v1.json +173 -0
  40. core_runtime/data/schemas/core/causal_trace.v1.json +141 -0
  41. core_runtime/data/schemas/core/context_gate.v1.json +38 -0
  42. core_runtime/data/schemas/core/context_threshold.v1.json +46 -0
  43. core_runtime/data/schemas/core/contract_program.v1.json +186 -0
  44. core_runtime/data/schemas/core/contract_program.v2.json +187 -0
  45. core_runtime/data/schemas/core/control_decision.v1.json +114 -0
  46. core_runtime/data/schemas/core/dsk.v3.json +105 -0
  47. core_runtime/data/schemas/core/effect_result.v1.json +39 -0
  48. core_runtime/data/schemas/core/entropy_signal.v1.json +108 -0
  49. core_runtime/data/schemas/core/execution_receipt.v1.json +93 -0
  50. core_runtime/data/schemas/core/frozen_release_manifest.v1.json +87 -0
  51. core_runtime/data/schemas/core/frozen_release_manifest.v2.json +72 -0
  52. core_runtime/data/schemas/core/frozen_release_manifest.v3.json +38 -0
  53. core_runtime/data/schemas/core/frozen_release_manifest.v4.json +72 -0
  54. core_runtime/data/schemas/core/frozen_release_manifest.v5.json +38 -0
  55. core_runtime/data/schemas/core/frozen_release_manifest.v6.json +116 -0
  56. core_runtime/data/schemas/core/frozen_release_manifest.v7.json +37 -0
  57. core_runtime/data/schemas/core/frozen_release_manifest.v8.json +114 -0
  58. core_runtime/data/schemas/core/frozen_rule_set.v1.json +282 -0
  59. core_runtime/data/schemas/core/memory_artifact.v1.json +120 -0
  60. core_runtime/data/schemas/core/memory_generation_result.v1.json +37 -0
  61. core_runtime/data/schemas/core/operational_learning_event.v1.json +63 -0
  62. core_runtime/data/schemas/core/pattern_candidate.v1.json +114 -0
  63. core_runtime/data/schemas/core/physical_safety_assurance_case.v1.json +676 -0
  64. core_runtime/data/schemas/core/policy_lifecycle.v1.json +99 -0
  65. core_runtime/data/schemas/core/retention_manifest.v1.json +53 -0
  66. core_runtime/data/schemas/core/reversibility_policy.v1.json +107 -0
  67. core_runtime/data/schemas/core/rule_anchor_batch.v1.json +93 -0
  68. core_runtime/data/schemas/core/rule_anchor_chain_evidence.v1.json +56 -0
  69. core_runtime/data/schemas/core/rule_approval.v1.json +49 -0
  70. core_runtime/data/schemas/core/rule_approval_request.v1.json +42 -0
  71. core_runtime/data/schemas/core/state_transition.v1.json +115 -0
  72. core_runtime/data/schemas/core/task_closeout.v1.json +47 -0
  73. core_runtime/data/schemas/core/template_promotion_candidate.v1.json +83 -0
  74. core_runtime/data/schemas/core/unsigned_rule_anchor_deployment.v1.json +106 -0
  75. core_runtime/data/schemas/core/unsigned_rule_anchor_transaction.v1.json +116 -0
  76. core_runtime/tooling/__init__.py +48 -0
  77. core_runtime/tooling/bump_version.py +900 -0
  78. core_runtime/tooling/contract_preflight.py +293 -0
  79. core_runtime/tooling/create_domain.py +254 -0
  80. core_runtime/tooling/diagnostics.py +129 -0
  81. core_runtime/tooling/doctor.py +482 -0
  82. core_runtime/tooling/file_inventory.py +182 -0
  83. core_runtime/tooling/json_checks.py +100 -0
  84. core_runtime/tooling/release_check.py +1017 -0
  85. core_runtime/tooling/repair_artifact_paths.py +458 -0
  86. core_runtime/tooling/report_writer.py +176 -0
  87. core_runtime/tooling/repository_inventory.py +399 -0
  88. core_runtime/tooling/safety_checks.py +172 -0
  89. core_runtime/tooling/sync_template.py +303 -0
  90. core_runtime/tooling/validation.py +507 -0
  91. core_runtime/tooling/version_inventory.py +256 -0
  92. core_runtime_engine-11.5.1.dist-info/METADATA +35 -0
  93. core_runtime_engine-11.5.1.dist-info/RECORD +96 -0
  94. core_runtime_engine-11.5.1.dist-info/WHEEL +5 -0
  95. core_runtime_engine-11.5.1.dist-info/entry_points.txt +2 -0
  96. core_runtime_engine-11.5.1.dist-info/top_level.txt +1 -0
@@ -0,0 +1,131 @@
1
+ """Closed deterministic replay for the public validation-only contract language."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import copy
6
+ from collections.abc import Mapping
7
+ from typing import Any, TypedDict
8
+
9
+ from core_runtime.core.canonicalization import canonical_json_hash
10
+ from core_runtime.core.contract_evaluator import evaluate_contract_payload, input_fingerprint
11
+ from core_runtime.core.contract_program_registry import execute_registry_operation
12
+
13
+
14
+ class ContractProgramExecution(TypedDict):
15
+ schema: str
16
+ status: str
17
+ authority: str
18
+ execution_authorized: bool
19
+ state_application_authorized: bool
20
+ program_fingerprint: str
21
+ input_fingerprint: str
22
+ emitted: list[dict[str, Any]]
23
+ staged_transitions: list[dict[str, str]]
24
+ errors: list[dict[str, str]]
25
+ execution_fingerprint: str
26
+
27
+
28
+ def _error(code: str, message: str, field: str) -> dict[str, str]:
29
+ return {"code": code, "message": message, "field": field}
30
+
31
+
32
+ def execute_contract_program(program: Mapping[str, Any], sealed_inputs: Mapping[str, Any]) -> ContractProgramExecution:
33
+ """Replay one closed program against caller-supplied sealed inputs.
34
+
35
+ This function neither reads external state nor applies transitions. A transition
36
+ instruction only records a candidate transition in the result for a separate,
37
+ explicitly authorized system to evaluate.
38
+ """
39
+
40
+ program_payload = copy.deepcopy(dict(program))
41
+ evaluation = evaluate_contract_payload(program_payload)
42
+ execution: dict[str, Any] = {
43
+ "schema": "core.contract_program_execution.v1",
44
+ "status": "rejected" if evaluation["status"] != "passed" else "passed",
45
+ "authority": "validation_only",
46
+ "execution_authorized": False,
47
+ "state_application_authorized": False,
48
+ "program_fingerprint": str(program_payload.get("fingerprint", "")),
49
+ "input_fingerprint": input_fingerprint(dict(sealed_inputs)),
50
+ "emitted": [],
51
+ "staged_transitions": [],
52
+ "errors": [],
53
+ }
54
+ if evaluation["status"] != "passed":
55
+ execution["errors"] = [
56
+ {"code": str(item["code"]), "message": str(item["message"]), "field": str(item["field"])}
57
+ for item in evaluation["errors"]
58
+ ]
59
+ else:
60
+ values: dict[str, Any] = {}
61
+ max_items = int(program_payload["limits"]["max_items"])
62
+ for index, instruction in enumerate(program_payload["instructions"]):
63
+ opcode = instruction["opcode"]
64
+ field = f"instructions[{index}]"
65
+ if opcode == "load":
66
+ key = instruction["key"]
67
+ if key not in sealed_inputs:
68
+ execution["status"] = "insufficient_data"
69
+ execution["errors"].append(_error("sealed_input_missing", "Required sealed input is absent.", f"{field}.key"))
70
+ break
71
+ values[instruction["output"]] = copy.deepcopy(sealed_inputs[key])
72
+ elif opcode == "assert":
73
+ key = instruction["key"]
74
+ if key not in sealed_inputs:
75
+ execution["status"] = "insufficient_data"
76
+ execution["errors"].append(_error("sealed_input_missing", "Required sealed input is absent.", f"{field}.key"))
77
+ break
78
+ if sealed_inputs[key] != instruction["equals"]:
79
+ execution["status"] = "blocked"
80
+ execution["errors"].append(_error("assertion_failed", "Sealed input does not match the declared assertion.", f"{field}.equals"))
81
+ break
82
+ elif opcode == "derive":
83
+ keys = instruction["input_keys"]
84
+ if any(key not in values for key in keys):
85
+ execution["status"] = "blocked"
86
+ execution["errors"].append(_error("derived_input_missing", "Derivation requires a prior output key.", f"{field}.input_keys"))
87
+ break
88
+ if instruction["operation"] == "copy":
89
+ values[instruction["output"]] = copy.deepcopy(values[keys[0]])
90
+ elif instruction["operation"] == "registry":
91
+ try:
92
+ values[instruction["output"]] = execute_registry_operation(
93
+ str(instruction["registry_key"]),
94
+ [values[key] for key in keys],
95
+ )
96
+ except (KeyError, TypeError, ValueError) as exc:
97
+ execution["status"] = "blocked"
98
+ execution["errors"].append(
99
+ _error("registry_operation_rejected", str(exc), f"{field}.registry_key")
100
+ )
101
+ break
102
+ else:
103
+ values[instruction["output"]] = len(keys)
104
+ elif opcode == "transition":
105
+ execution["staged_transitions"].append(
106
+ {
107
+ "transition_id": instruction["transition_id"],
108
+ "before_ref": instruction["before_ref"],
109
+ "after_ref": instruction["after_ref"],
110
+ "reversibility_class": instruction["reversibility_class"],
111
+ }
112
+ )
113
+ elif opcode == "emit":
114
+ key = instruction["value_key"]
115
+ if key not in values:
116
+ execution["status"] = "blocked"
117
+ execution["errors"].append(_error("emitted_value_missing", "Emit requires a prior output key.", f"{field}.value_key"))
118
+ break
119
+ execution["emitted"].append({"code": instruction["code"], "value": copy.deepcopy(values[key])})
120
+ elif opcode == "halt":
121
+ execution["status"] = instruction["status"]
122
+
123
+ if len(values) > max_items:
124
+ execution["status"] = "blocked"
125
+ execution["errors"].append(_error("runtime_item_limit_exceeded", "Runtime output count exceeds max_items.", "limits.max_items"))
126
+ break
127
+
128
+ if execution["status"] != "passed":
129
+ execution["staged_transitions"] = []
130
+ execution["execution_fingerprint"] = f"sha256:{canonical_json_hash(execution)}"
131
+ return execution # type: ignore[return-value]
@@ -0,0 +1,104 @@
1
+ """Finite registry-only operations for the isolated ContractProgram fork.
2
+
3
+ This module deliberately exposes a small, versioned operation surface. It is
4
+ not a dynamic evaluator and it never loads executable configuration from a
5
+ declaration.
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ import re
11
+ from collections.abc import Mapping, Sequence
12
+ from typing import Any
13
+
14
+ REGISTRY_VERSION = "core.contract_program.registry.v1"
15
+ REGISTRY_KEYS = frozenset(
16
+ {
17
+ "rank.quantity.v1",
18
+ "member.scale_adapter.v1",
19
+ "regex.grammar_context.v1",
20
+ }
21
+ )
22
+ OPERATION_ALLOWLIST = frozenset(
23
+ {
24
+ "equals",
25
+ "distinct_count",
26
+ "is_nonempty_string",
27
+ "rank_of",
28
+ "min_of",
29
+ "compare",
30
+ "logical_and",
31
+ "logical_or",
32
+ "logical_not",
33
+ "member_of",
34
+ "regex_match",
35
+ }
36
+ )
37
+ FORBIDDEN_CONSTRUCTS = frozenset(
38
+ {"loop", "branch", "jump", "dynamic_import", "eval", "callback", "inline_policy"}
39
+ )
40
+
41
+ _GRAMMARS = {
42
+ "qualified_ref": re.compile(r"^[a-z][a-z0-9_.-]{2,}:[^\s]{3,}$", re.IGNORECASE),
43
+ "identifier": re.compile(r"^[A-Za-z][A-Za-z0-9_.-]{0,127}$"),
44
+ }
45
+
46
+
47
+ class RegistryOperationError(ValueError):
48
+ """Raised when a candidate requests an operation outside the registry."""
49
+
50
+
51
+ def _require_arity(inputs: Sequence[Any], expected: int) -> None:
52
+ if len(inputs) != expected:
53
+ raise RegistryOperationError(f"registry operation requires {expected} inputs")
54
+
55
+
56
+ def execute_registry_operation(registry_key: str, inputs: Sequence[Any]) -> Any:
57
+ """Execute one deterministic, allowlisted registry operation."""
58
+
59
+ if registry_key not in REGISTRY_KEYS:
60
+ raise RegistryOperationError(f"unknown registry key: {registry_key!r}")
61
+ if not isinstance(inputs, Sequence) or isinstance(inputs, (str, bytes)):
62
+ raise RegistryOperationError("registry inputs must be a finite sequence")
63
+
64
+ if registry_key == "rank.quantity.v1":
65
+ _require_arity(inputs, 1)
66
+ value = inputs[0]
67
+ if isinstance(value, bool) or not isinstance(value, int) or value < 0:
68
+ raise RegistryOperationError("quantity rank must be a non-negative integer")
69
+ return value
70
+
71
+ if registry_key == "member.scale_adapter.v1":
72
+ _require_arity(inputs, 4)
73
+ adapter_from, adapter_to, requested_from, requested_to = inputs
74
+ return adapter_from == requested_from and adapter_to == requested_to
75
+
76
+ _require_arity(inputs, 2)
77
+ value, grammar_name = inputs
78
+ if not isinstance(value, str) or not isinstance(grammar_name, str):
79
+ return False
80
+ grammar = _GRAMMARS.get(grammar_name)
81
+ if grammar is None:
82
+ raise RegistryOperationError(f"unknown grammar context: {grammar_name!r}")
83
+ return bool(grammar.fullmatch(value))
84
+
85
+
86
+ def validate_registry_program(program: Mapping[str, Any]) -> list[str]:
87
+ """Return deterministic profile errors for a candidate program."""
88
+
89
+ errors: list[str] = []
90
+ instructions = program.get("instructions", [])
91
+ if not isinstance(instructions, list):
92
+ return ["instructions must be a list"]
93
+ for index, instruction in enumerate(instructions):
94
+ if not isinstance(instruction, Mapping):
95
+ errors.append(f"instructions[{index}] is not an object")
96
+ continue
97
+ for key in FORBIDDEN_CONSTRUCTS:
98
+ if key in instruction:
99
+ errors.append(f"forbidden construct {key!r} at instructions[{index}]")
100
+ if instruction.get("opcode") == "derive" and instruction.get("operation") == "registry":
101
+ registry_key = instruction.get("registry_key")
102
+ if registry_key not in REGISTRY_KEYS:
103
+ errors.append(f"unknown registry key at instructions[{index}]")
104
+ return errors
@@ -0,0 +1,126 @@
1
+ #!/usr/bin/env python3
2
+ """ContractProgram v2 — Contract-Oriented Reproducible Evaluation.
3
+
4
+ Traverses 6 eslabones (PERFIL→VOCABULARIO→QUERYSPEC→RESULTADO→VISTA→EVIDENCIA),
5
+ validates DSK declarations at each crossing, emits one of 9 verdicts.
6
+
7
+ Deterministic. No LLM. Same input → same verdict.
8
+ """
9
+ from __future__ import annotations
10
+ import hashlib, json, sys
11
+ from typing import Any
12
+
13
+ SCHEMA_VERSION = "core.contract_program.v2"
14
+ ESLABONES = ["PERFIL", "VOCABULARIO", "QUERYSPEC", "RESULTADO", "VISTA", "EVIDENCIA"]
15
+ VERDICTS = [
16
+ "pass", "incomplete", "scale_violation", "authority_violation",
17
+ "loss_undeclared", "temporal_violation", "translation_missing",
18
+ "intent_unconfirmed", "aborted"
19
+ ]
20
+
21
+
22
+ def evaluate_contract_v2(contract: dict[str, Any]) -> dict[str, Any]:
23
+ """Evaluate a ContractProgram v2 contract. Returns verdict + findings."""
24
+ findings: list[dict[str, str]] = []
25
+
26
+ # Validate structure
27
+ eslabones = contract.get("eslabones", [])
28
+ if len(eslabones) != 6:
29
+ findings.append({"eslabon": "ALL", "code": "incomplete", "detail": f"expected 6 eslabones, got {len(eslabones)}"})
30
+ return _result(contract, "incomplete", findings)
31
+
32
+ # Check order and names
33
+ for i, expected_name in enumerate(ESLABONES):
34
+ eslabon = eslabones[i] if i < len(eslabones) else {}
35
+ name = eslabon.get("name", "")
36
+ if name != expected_name:
37
+ findings.append({"eslabon": f"order_{i}", "code": "incomplete",
38
+ "detail": f"position {i} expected {expected_name}, got {name}"})
39
+
40
+ if any(f["code"] == "incomplete" for f in findings):
41
+ return _result(contract, "incomplete", findings)
42
+
43
+ # Validate DSK declarations at each crossing
44
+ for eslabon in eslabones:
45
+ name = eslabon.get("name", "")
46
+ dsk = eslabon.get("dsk_declaration", {})
47
+
48
+ # Check composition_rule
49
+ if not dsk.get("composition_rule"):
50
+ findings.append({"eslabon": name, "code": "scale_violation",
51
+ "detail": "missing composition_rule"})
52
+
53
+ # Check declared_loss
54
+ loss = dsk.get("declared_loss", {})
55
+ if not loss.get("properties") or not loss.get("evidence_refs"):
56
+ findings.append({"eslabon": name, "code": "loss_undeclared",
57
+ "detail": "declared_loss missing properties or evidence_refs"})
58
+
59
+ # Check authority_ceiling
60
+ auth = dsk.get("authority_ceiling", "")
61
+ if auth not in ("reference_only", "advisory_only", "domain_authoritative", "externally_validated"):
62
+ findings.append({"eslabon": name, "code": "authority_violation",
63
+ "detail": f"invalid authority_ceiling: {auth}"})
64
+
65
+ # Check temporal_invariant if present
66
+ ti = dsk.get("temporal_invariant")
67
+ if ti is not None:
68
+ if not ti.get("captured_at") or not ti.get("valid_until"):
69
+ findings.append({"eslabon": name, "code": "temporal_violation",
70
+ "detail": "temporal_invariant missing captured_at or valid_until"})
71
+
72
+ # Check translation_map if present
73
+ tm = dsk.get("translation_map")
74
+ if tm is not None:
75
+ if not tm.get("source_field") or not tm.get("target_field"):
76
+ findings.append({"eslabon": name, "code": "translation_missing",
77
+ "detail": "translation_map missing source_field or target_field"})
78
+
79
+ # Check paraphrase_intent if present
80
+ pi = dsk.get("paraphrase_intent")
81
+ if pi is not None:
82
+ if pi.get("confirmed_by") not in ("operator", "agent"):
83
+ findings.append({"eslabon": name, "code": "intent_unconfirmed",
84
+ "detail": f"paraphrase_intent.confirmed_by={pi.get('confirmed_by')!r} invalid"})
85
+ elif pi.get("confirmed_by") == "agent":
86
+ findings.append({"eslabon": name, "code": "intent_unconfirmed",
87
+ "detail": "paraphrase_intent.confirmed_by=agent (not operator)"})
88
+
89
+ # Determine verdict from findings
90
+ if not findings:
91
+ verdict = "pass"
92
+ else:
93
+ # First non-pass finding determines verdict
94
+ verdict = findings[0]["code"]
95
+ if verdict not in VERDICTS:
96
+ verdict = "aborted"
97
+
98
+ return _result(contract, verdict, findings)
99
+
100
+
101
+ def _result(contract: dict, verdict: str, findings: list[dict]) -> dict[str, Any]:
102
+ payload = json.dumps(contract, sort_keys=True)
103
+ fp = "sha256:" + hashlib.sha256(payload.encode()).hexdigest()
104
+ return {
105
+ "schema_version": SCHEMA_VERSION,
106
+ "contract_id": contract.get("contract_id", ""),
107
+ "verdict": verdict,
108
+ "findings": findings,
109
+ "fingerprint": fp,
110
+ "deterministic": True,
111
+ "llm_used": False,
112
+ }
113
+
114
+
115
+ def main(argv: list[str]) -> int:
116
+ if len(argv) < 2:
117
+ print("Usage: contract_program_v2.py <contract.json>", file=sys.stderr)
118
+ return 1
119
+ contract = json.load(open(argv[1]))
120
+ result = evaluate_contract_v2(contract)
121
+ print(json.dumps(result, indent=2, sort_keys=True))
122
+ return 0 if result["verdict"] == "pass" else 1
123
+
124
+
125
+ if __name__ == "__main__":
126
+ sys.exit(main(sys.argv[1:]))
@@ -0,0 +1,142 @@
1
+ """Deterministic Scale Kernel v3 evaluator.
2
+
3
+ The kernel validates one typed scale crossing. It never calls a provider,
4
+ consults a domain or increases the authority declared by the input.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ import json
10
+ from decimal import Decimal, InvalidOperation
11
+ from importlib.resources import files
12
+ from pathlib import Path
13
+ from typing import Any
14
+
15
+ from jsonschema import Draft7Validator
16
+
17
+ from core_runtime.core.rule_anchor import canonical_fingerprint
18
+
19
+ SCHEMA_VERSION = "core.dsk.v3"
20
+ SCHEMA_PATH = files("core_runtime").joinpath("data", "schemas", "core", "dsk.v3.json")
21
+ STATUSES = ("pass", "invalid", "insufficient_data", "blocked")
22
+
23
+
24
+ def _error(code: str, message: str, field: str | None = None) -> dict[str, str]:
25
+ result = {"code": code, "message": message}
26
+ if field is not None:
27
+ result["field"] = field
28
+ return result
29
+
30
+
31
+ def _decimal(value: Any) -> Decimal:
32
+ if isinstance(value, bool):
33
+ raise InvalidOperation
34
+ return Decimal(str(value))
35
+
36
+
37
+ def _decimal_text(value: Decimal) -> str:
38
+ if value == 0:
39
+ return "0"
40
+ return format(value.normalize(), "f")
41
+
42
+
43
+ def _decimal_places(value: Decimal) -> int:
44
+ text = _decimal_text(value)
45
+ return len(text.partition(".")[2])
46
+
47
+
48
+ def _envelope(payload: dict[str, Any], status: str, errors: list[dict[str, str]], **extra: Any) -> dict[str, Any]:
49
+ result: dict[str, Any] = {
50
+ "schema": SCHEMA_VERSION,
51
+ "status": status,
52
+ "errors": errors,
53
+ "fingerprint": canonical_fingerprint(payload),
54
+ "deterministic": True,
55
+ "llm_used": False,
56
+ }
57
+ result.update(extra)
58
+ return result
59
+
60
+
61
+ def _schema_errors(payload: Any) -> list[dict[str, str]]:
62
+ schema = json.loads(SCHEMA_PATH.read_text(encoding="utf-8"))
63
+ return [
64
+ _error("schema_validation_error", item.message, ".".join(map(str, item.absolute_path)) or "$")
65
+ for item in sorted(Draft7Validator(schema).iter_errors(payload), key=lambda item: list(item.absolute_path))
66
+ ]
67
+
68
+
69
+ def evaluate_dsk_v3(payload: dict[str, Any]) -> dict[str, Any]:
70
+ """Evaluate a DSK v3 declaration and return the standard CORE envelope."""
71
+
72
+ if not isinstance(payload, dict):
73
+ return _envelope({}, "invalid", [_error("payload_type_invalid", "DSK input must be an object.")])
74
+ schema_errors = _schema_errors(payload)
75
+ if schema_errors:
76
+ return _envelope(payload, "invalid", schema_errors)
77
+
78
+ crossing = payload["crossing"]
79
+ source = crossing["source"]
80
+ target = crossing["target"]
81
+ conversion = crossing["conversion"]
82
+ authority = payload["authority"]
83
+ if "value" not in source:
84
+ return _envelope(payload, "insufficient_data", [_error("source_value_missing", "source.value is required to evaluate the crossing.", "crossing.source.value")])
85
+
86
+ errors: list[dict[str, str]] = []
87
+ if source["unit"] != conversion["source_unit"] or target["unit"] != conversion["target_unit"]:
88
+ errors.append(_error("scale_violation", "Declared conversion units do not match the crossing endpoints.", "crossing.conversion"))
89
+
90
+ ceiling = authority["ceiling"]
91
+ if ceiling in {"domain_authoritative", "externally_validated"} and authority["source"] != "external_validator":
92
+ errors.append(_error("authority_non_amplification", "A scale crossing cannot create authority without an external validator.", "authority"))
93
+
94
+ try:
95
+ value = _decimal(source["value"])
96
+ converted = value * Decimal(conversion["numerator"]) / Decimal(conversion["denominator"])
97
+ except (InvalidOperation, ZeroDivisionError):
98
+ return _envelope(payload, "invalid", [_error("numeric_value_invalid", "Numeric values must be finite and deterministic.", "crossing.source.value")])
99
+
100
+ policies = payload.get("policies", {})
101
+ discrete = policies.get("discrete_multiple")
102
+ if discrete is not None and converted % Decimal(discrete["multiple"]) != 0:
103
+ errors.append(_error("discrete_multiple_violation", "Converted value is not an allowed discrete multiple.", "policies.discrete_multiple"))
104
+
105
+ resolution = policies.get("resolution")
106
+ if resolution is not None and _decimal_places(converted) > resolution["max_decimal_places"]:
107
+ errors.append(_error("resolution_violation", "Converted value exceeds the declared resolution.", "policies.resolution"))
108
+
109
+ threshold = policies.get("threshold")
110
+ if threshold is not None and converted < Decimal(str(threshold["minimum_value"])):
111
+ errors.append(_error("threshold_ineligible", "Threshold eligibility was not met; no authority is created.", "policies.threshold"))
112
+
113
+ if errors:
114
+ return _envelope(payload, "blocked", errors, authority_ceiling=ceiling)
115
+
116
+ return _envelope(
117
+ payload,
118
+ "pass",
119
+ [],
120
+ result={
121
+ "resource": target["resource"],
122
+ "unit": target["unit"],
123
+ "value": _decimal_text(converted),
124
+ "authority_ceiling": ceiling,
125
+ "composition_rule": crossing["composition_rule"],
126
+ "declared_loss": crossing["declared_loss"],
127
+ },
128
+ )
129
+
130
+
131
+ def main(argv: list[str]) -> int:
132
+ if len(argv) != 2:
133
+ print("Usage: dsk_v3.py <declaration.json>", file=__import__("sys").stderr)
134
+ return 2
135
+ payload = json.loads(Path(argv[1]).read_text(encoding="utf-8"))
136
+ result = evaluate_dsk_v3(payload)
137
+ print(json.dumps(result, indent=2, ensure_ascii=False, sort_keys=True))
138
+ return 0 if result["status"] == "pass" else 1
139
+
140
+
141
+ if __name__ == "__main__":
142
+ raise SystemExit(main(__import__("sys").argv))