behavior-contracts 0.8.2__tar.gz → 0.8.4__tar.gz

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 (27) hide show
  1. {behavior_contracts-0.8.2 → behavior_contracts-0.8.4}/PKG-INFO +1 -1
  2. {behavior_contracts-0.8.2 → behavior_contracts-0.8.4}/pyproject.toml +1 -1
  3. {behavior_contracts-0.8.2 → behavior_contracts-0.8.4}/src/behavior_contracts/__init__.py +1 -1
  4. {behavior_contracts-0.8.2 → behavior_contracts-0.8.4}/src/behavior_contracts/behavior.py +8 -0
  5. {behavior_contracts-0.8.2 → behavior_contracts-0.8.4}/src/behavior_contracts/conformance.py +13 -2
  6. {behavior_contracts-0.8.2 → behavior_contracts-0.8.4}/src/behavior_contracts.egg-info/PKG-INFO +1 -1
  7. {behavior_contracts-0.8.2 → behavior_contracts-0.8.4}/tests/test_codegen_generated.py +1 -1
  8. {behavior_contracts-0.8.2 → behavior_contracts-0.8.4}/tests/test_public_api.py +1 -1
  9. {behavior_contracts-0.8.2 → behavior_contracts-0.8.4}/README.md +0 -0
  10. {behavior_contracts-0.8.2 → behavior_contracts-0.8.4}/setup.cfg +0 -0
  11. {behavior_contracts-0.8.2 → behavior_contracts-0.8.4}/src/behavior_contracts/canonical.py +0 -0
  12. {behavior_contracts-0.8.2 → behavior_contracts-0.8.4}/src/behavior_contracts/codec.py +0 -0
  13. {behavior_contracts-0.8.2 → behavior_contracts-0.8.4}/src/behavior_contracts/envelope.py +0 -0
  14. {behavior_contracts-0.8.2 → behavior_contracts-0.8.4}/src/behavior_contracts/expr_eval.py +0 -0
  15. {behavior_contracts-0.8.2 → behavior_contracts-0.8.4}/src/behavior_contracts/fingerprint.py +0 -0
  16. {behavior_contracts-0.8.2 → behavior_contracts-0.8.4}/src/behavior_contracts/guard.py +0 -0
  17. {behavior_contracts-0.8.2 → behavior_contracts-0.8.4}/src/behavior_contracts/plan.py +0 -0
  18. {behavior_contracts-0.8.2 → behavior_contracts-0.8.4}/src/behavior_contracts/primitives.py +0 -0
  19. {behavior_contracts-0.8.2 → behavior_contracts-0.8.4}/src/behavior_contracts/template.py +0 -0
  20. {behavior_contracts-0.8.2 → behavior_contracts-0.8.4}/src/behavior_contracts.egg-info/SOURCES.txt +0 -0
  21. {behavior_contracts-0.8.2 → behavior_contracts-0.8.4}/src/behavior_contracts.egg-info/dependency_links.txt +0 -0
  22. {behavior_contracts-0.8.2 → behavior_contracts-0.8.4}/src/behavior_contracts.egg-info/entry_points.txt +0 -0
  23. {behavior_contracts-0.8.2 → behavior_contracts-0.8.4}/src/behavior_contracts.egg-info/requires.txt +0 -0
  24. {behavior_contracts-0.8.2 → behavior_contracts-0.8.4}/src/behavior_contracts.egg-info/top_level.txt +0 -0
  25. {behavior_contracts-0.8.2 → behavior_contracts-0.8.4}/tests/test_conformance.py +0 -0
  26. {behavior_contracts-0.8.2 → behavior_contracts-0.8.4}/tests/test_plan_parallel.py +0 -0
  27. {behavior_contracts-0.8.2 → behavior_contracts-0.8.4}/tests/test_primitives.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: behavior-contracts
3
- Version: 0.8.2
3
+ Version: 0.8.4
4
4
  Summary: Multi-language IR-Runtime common core (Python port). The COMMON 'thin core' primitives from dsl-contracts runtime-boundary.md — validate_envelope / evaluate_expression / render_template / run_plan / canonical_value / canonical_json / py_float_repr / assert_portable — with zero backend (DynamoDB/graphddb) dependencies.
5
5
  Author: foo-log
6
6
  License: MIT
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "behavior-contracts"
7
- version = "0.8.2"
7
+ version = "0.8.4"
8
8
  description = "Multi-language IR-Runtime common core (Python port). The COMMON 'thin core' primitives from dsl-contracts runtime-boundary.md — validate_envelope / evaluate_expression / render_template / run_plan / canonical_value / canonical_json / py_float_repr / assert_portable — with zero backend (DynamoDB/graphddb) dependencies."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.9"
@@ -22,7 +22,7 @@ SPEC_VERSIONS = {
22
22
  "template": 1,
23
23
  "plan": 1,
24
24
  "canonical": 2, # v2: obj 値の __proto__ own key を FORBIDDEN_KEY に(fail-closed)
25
- "behavior": 4, # v4(#128/A6・SCP-only): provenance token + 全ノード型確定を serialized-IR 不変条件へ格上げ(released 3=fanout を retire)。v1–v3 意味論は不変だが旧 runtime(behavior≤3)は新 IR を loud reject する(機構 = 生成モジュールの baked-spec-skew ゲート[EXPECTED_SPEC_VERSIONS.behavior vs runtime] + conformance pre-flight version fail-closed。validate_envelope は envelope の specVersion「major.minor」文字列を見るのであって behaviorVersion 整数ではない)
25
+ "behavior": 5, # v5: an OMITTED input key for a port DECLARED optional (inputPorts[name].required === false — the opt portable-type constructor) binds to null; the runner reads the component's own inputPorts declaration when building the entry scope. A required port / an undeclared name is unaffected (still UNKNOWN_BINDING). An old runtime (behavior<=4) raises UNKNOWN_BINDING where a v5 vector expects the bound null, so v5 vectors are fail-closed against it by the conformance pre-flight version gate. | 旧 v4 # v4(#128/A6・SCP-only): provenance token + 全ノード型確定を serialized-IR 不変条件へ格上げ(released 3=fanout を retire)。v1–v3 意味論は不変だが旧 runtime(behavior≤3)は新 IR を loud reject する(機構 = 生成モジュールの baked-spec-skew ゲート[EXPECTED_SPEC_VERSIONS.behavior vs runtime] + conformance pre-flight version fail-closed。validate_envelope は envelope の specVersion「major.minor」文字列を見るのであって behaviorVersion 整数ではない)
26
26
  "guard": 2, # v2(#128/A6): assert_compiled + UNTYPED_NODE + operator 型シグネチャ SSoT の accept/reject を vector-pin(v1 は bc#25 の可搬性 pin のみ)
27
27
  "c2": 1, # 初版(bc#28: c2-catalog-swap — catalog-swap 実行 + IR 構造一致の 5 言語 pin)
28
28
  "provenance": 1, # 初版(#128/A6): シリアライズ境界の canonical fingerprint 照合(改竄/stale の 5 言語 loud reject)+ 非空虚性(CONFORMANCE_MUTATE)
@@ -159,6 +159,14 @@ def run_behavior(
159
159
  if comp is None:
160
160
  _bfail("UNKNOWN_ENTRY", f"component '{entry if entry is not None else '<first>'}' not found in IR")
161
161
 
162
+ # `{opt:T}` と宣言された input port(PortSchema ``required: False``)は **省略可**で、値域は
163
+ # ``T | None``。「キーごと省略」と「None を渡す」は同じ「値が無い」の 2 通りの綴りなので、省略
164
+ # されたキーは None に束縛する(可搬 IR が既に持つ宣言を読むだけ)。required な port と未宣言の
165
+ # 名前は束縛しない: 未束縛のまま参照されれば ``UNKNOWN_BINDING``(fail-closed はそのまま)。
166
+ for _p_name, _p_schema in (comp.get("inputPorts") or {}).items():
167
+ if isinstance(_p_schema, Mapping) and _p_schema.get("required") is False and _p_name not in input:
168
+ input[_p_name] = None
169
+
162
170
  body: List[Mapping[str, Any]] = list(comp["body"])
163
171
  id_to_index = {n["id"]: i for i, n in enumerate(body)}
164
172
 
@@ -264,6 +264,8 @@ def _build_handlers(spec: Dict[str, Any]):
264
264
  v2 の観測用 outcome(PROTOCOL.md §3.5):
265
265
  ``{"echo":"ctx"}`` → ``{ok: {nodeId, component}}``(handler ctx の中身を返す)
266
266
  ``{"echo":"items"}`` → ``{ok: ports["items"]}``(batched handler が受け取った items)
267
+ ``{"echo":"port","port":"<name>"}`` → ``{ok: ports["<name>"]}``(当該 port が受け取った値その
268
+ ものを結果にして **port 面を可観測**にする。受け取っていない port は null)
267
269
  """
268
270
  handlers = {}
269
271
  for name, raw in spec.items():
@@ -282,10 +284,19 @@ def _build_handlers(spec: Dict[str, Any]):
282
284
  else:
283
285
  with lock:
284
286
  o = queue.pop(0) if len(queue) > 1 else queue[0]
285
- if o.get("echo") == "ctx":
287
+ echo = o.get("echo")
288
+ if echo == "ctx":
286
289
  return {"ok": {"nodeId": ctx["nodeId"], "component": ctx["component"]}}
287
- if o.get("echo") == "items":
290
+ if echo == "items":
288
291
  return {"ok": ports.get("items")}
292
+ if echo == "port":
293
+ return {"ok": ports.get(o.get("port"))}
294
+ # 閉集合外の echo は vector 記述ミス — LOUD に落とす(PROTOCOL.md §3.5)。
295
+ # ok/error 読みへ落として黙って誤判定しない。
296
+ if echo is not None:
297
+ raise ValueError(
298
+ f'conformance: unknown echo directive {echo!r} (expected "ctx" | "items" | "port")'
299
+ )
289
300
  if "ok" in o:
290
301
  return {"ok": decode_value(o["ok"])}
291
302
  return {"error": o["error"]}
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: behavior-contracts
3
- Version: 0.8.2
3
+ Version: 0.8.4
4
4
  Summary: Multi-language IR-Runtime common core (Python port). The COMMON 'thin core' primitives from dsl-contracts runtime-boundary.md — validate_envelope / evaluate_expression / render_template / run_plan / canonical_value / canonical_json / py_float_repr / assert_portable — with zero backend (DynamoDB/graphddb) dependencies.
5
5
  Author: foo-log
6
6
  License: MIT
@@ -110,7 +110,7 @@ def test_tampered_generated_module_is_loudly_rejected(tmp_path):
110
110
  code = f.read()
111
111
 
112
112
  # spec-version skew(焼き込み定数の改変)→ ロード時 RuntimeError。
113
- skew = code.replace('"behavior": 4', '"behavior": 99')
113
+ skew = code.replace('"behavior": 5', '"behavior": 99')
114
114
  assert skew != code
115
115
  p = tmp_path / "skew.py"
116
116
  p.write_text(skew, encoding="utf-8")
@@ -469,7 +469,7 @@ class TestValidateEnvelope:
469
469
  "template": 1,
470
470
  "plan": 1,
471
471
  "canonical": 2,
472
- "behavior": 4,
472
+ "behavior": 5,
473
473
  "guard": 2,
474
474
  "c2": 1,
475
475
  "provenance": 1,