diff --git a/CHANGELOG.md b/CHANGELOG.md index c517bce..0d63153 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,17 @@ # Changelog +## Unreleased + +- Added a public `PTCNAEngine` receipt spanning neural, circle, seed, and core. +- Added a deterministic hashed-linear fallback behind the same task interface. +- Added explicit, attributed fallback routing; target failures still raise by + default. +- Added immutable evaluation plans and terminal evidence receipts that freeze + workload, training schedule, comparator, post-training metric, thresholds, + resource limits, stopping, and failure propagation before execution. +- Removed the broken deprecated FastAPI seed runner that imported nonexistent + `src.core` modules; `PTCNARuntime` is its supported replacement. + ## 0.1.1 — 2026-07-29 - Added the shared `ptcna.circle.CircleTensor` and one structural composition diff --git a/README.md b/README.md index 9408cc2..466924b 100644 --- a/README.md +++ b/README.md @@ -41,6 +41,48 @@ pip install -e ".[dev]" # neural layer needs numpy; seed/core are stdlib-on pytest # testpaths = ptcna ``` +## Experimental runtime and dependable fallback + +The intended architecture and the simpler fallback share one task interface but +retain separate identities. PTCNA is selected by default. A target error raises +unless the caller explicitly enables fallback routing; every receipt records the +backend actually used. + +```python +from ptcna import PTCNARuntime + +runtime = PTCNARuntime() +target = runtime.infer("question") +fallback = runtime.infer("question", backend="fallback") +continued = runtime.infer("question", fallback_on_error=True) +runtime.reward(continued, outcome=1.0) +``` + +Freeze a representative labeled workload before inspecting outcomes: + +```python +from ptcna import EvaluationCase, EvaluationPlan, evaluate + +plan = EvaluationPlan( + plan_id="representative-workload-v1", + workload=(EvaluationCase("case-1", "input", "phi"),), + minimum_target_accuracy=0.80, + maximum_target_deficit_vs_fallback=0.00, + training_epochs=3, + reward_outcome=1.0, + repetitions=3, + max_training_steps=9, + max_case_evaluations=3, + max_seconds=30.0, + backend_error_status="FALSIFIED", +) +print(plan.digest) # preserve this with the plan before execution +receipt = evaluate(plan) +``` + +The repository does not ship a pretend representative workload. Until one is +frozen and executed, whether PTCNA works remains `hmmm`. + ## Status Alpha (`0.1.1`). All four layers import and the repository test suite passes. @@ -54,6 +96,13 @@ The layer boundary is now executable rather than only descriptive: reviewed PTCNA-specific higher-gonol producer profile exists. - EDCM remains an external authority. `ZetaEngine` accepts an explicitly injected measurement provider; PTCNA contains no shadow EDCM module. +- `PTCNAEngine` joins the live neural engine to the complete local core and + reports all four layers. `PTCNARuntime` keeps that experimental path distinct + from `HashedLinearFallback`; failover is explicit and attributed. +- `EvaluationPlan` freezes workload, training schedule, comparator, metric, + thresholds, resource limits, stopping, and failure propagation before + `evaluate` emits + `FALSIFIED`, `SURVIVED — not proved`, or `UNRESOLVED`. The core layer still intentionally exposes PTCA-named public objects such as `PTCATensor` and `PTCAInstance`; those names live in the correct layer. diff --git a/docs/architecture.md b/docs/architecture.md index 4f88efa..7ed022b 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -97,6 +97,14 @@ or criterion change. PTCNA-local prime and ring structures may be constructed now; only a claim that they are UCNS-produced remains suspended until an exact pinned UCNS receipt exists. +The executable boundary lives in `ptcna.runtime`: `PTCNAEngine` reports all +four live layers, `HashedLinearFallback` remains separately identified, and +`PTCNARuntime` raises on target failure unless fallback routing is explicitly +enabled. `ptcna.evaluation` accepts only an immutable, digest-bearing +`EvaluationPlan`, trains before scoring, and records the terminal verdict before repair. No +representative workload is bundled; selecting one remains evidence work, not a +construction prerequisite. + Semantic authority for discovery-before-recovery remains with `The-Interdependency/metapat`; this correction consulted `metapat@53315e30c54aba881a5b48cbf395890e83ab05c5`, @@ -105,6 +113,12 @@ METAPAT canon. ## Status log +- **2026-08-17 — executable construction/evaluation boundary.** Added the + four-layer target receipt, independently test-backed hashed-linear fallback, + explicit attributed failover, and frozen evaluation/verdict API. Removed the + broken deprecated FastAPI seed runner. This establishes runnable separation; + it does not establish that PTCNA works on a representative task. + - **2026-07-05 — circle/seed audit extraction (branch `claude/circle-extraction`).** Aggregation moved out of the neural engine into the layers that own it: `PCNAEngine._pcta_circle_audit` → `ptcna.circle.circle_audit`; diff --git a/docs/work-graphs/repository-plan-report.json b/docs/work-graphs/repository-plan-report.json index a12a7e9..f9f6293 100644 --- a/docs/work-graphs/repository-plan-report.json +++ b/docs/work-graphs/repository-plan-report.json @@ -49,8 +49,8 @@ } }, "status": { - "state": "active alpha runtime; intended architecture and dependable fallback construction proceed under separate evidence boundaries", - "current_claim": "PTCNA 0.1.1 implements one four-layer runtime in which reverse-mode gradients are owned by the neural layer while circle, seed, and core remain non-differentiating structural hosts. Construction of the intended PTCNA architecture may proceed under PTCNA-local provenance alongside a dependable explicit fallback. UCNS higher-gonol attribution remains suspended, EDCM remains external, and the critical 'does it work?' verdict remains unearned until frozen evaluation.", + "state": "active alpha runtime; explicit target, fallback, and frozen-verdict interfaces are implemented under separate evidence identities", + "current_claim": "PTCNA 0.1.1 implements one four-layer runtime in which reverse-mode gradients are owned by the neural layer while circle, seed, and core remain non-differentiating structural hosts. The unreleased package surface adds an attributed four-layer target receipt, an independently test-backed hashed-linear fallback, explicit failover, and immutable evaluation plans. UCNS higher-gonol attribution remains suspended, EDCM remains external, and the critical 'does it work?' verdict remains unearned until a representative plan is frozen and executed.", "latest_main_milestone": { "commit": "4509d33419aa25e6a9cfef415055e378b8f37edc", "description": "merged the reconciled four-layer v0.1.1 runtime with one CircleTensor, neural-only reverse-mode scalar ownership, fail-closed UCNS integration, and external EDCM measurement injection" @@ -81,32 +81,32 @@ "surface": "0.1.1 cross-repository input manifest", "status": "sealed historical coordination record", "boundary": "its July producer identities are evidence for the 0.1.1 reconciliation only, not current stack identities" + }, + { + "surface": "explicit target/fallback runtime boundary", + "status": "implemented and contract-tested on the unreleased package surface", + "boundary": "the fallback is separately identified and used after target failure only when the caller explicitly enables attributed failover" + }, + { + "surface": "frozen evaluation and terminal receipt API", + "status": "implemented and contract-tested infrastructure", + "boundary": "the API freezes training and scoring criteria and records verdicts but does not supply a representative workload or establish that either backend is useful" } ], "active_frontier": [ "keep the operational shell aligned with current skill-lib doctrine and supported GitHub Actions runtimes without changing PTCNA architectural evidence standing", - "construct the intended PTCNA architecture faithfully under PTCNA-local provenance without waiting for upstream validation or a simpler baseline to grant permission", - "build and independently verify a dependable simpler fallback behind an explicit interface so useful operation survives a PTCNA failure without silently replacing or redefining PTCNA", - "freeze the critical 'does it work?' evaluation before outcome inspection, including representative workload, comparator, exact metric and aggregation, threshold, resource bounds, stopping rules, failure propagation, and evidence receipt", + "freeze a representative 'does it work?' EvaluationPlan before outcome inspection, including workload, training epochs and reward, exact thresholds, repetitions, resource bounds, and failure propagation; the comparator identity, post-training metric, aggregation, stopping rule, and receipt schema are now executable", + "execute the preserved plan without repair or criterion change and record FALSIFIED, SURVIVED — not proved, or UNRESOLVED", + "qualify whether the hashed-linear fallback preserves useful operation on the representative workload rather than inferring utility from deterministic contract tests", "consume exact UCNS producer receipts when available for UCNS attribution while allowing locally attributed PTCNA prime and ring construction to continue", "resolve whether the embedded ZetaEngine remains a bounded PTCNA-local measurement-to-learning adapter or should be removed in favor of separate ZFAE authority before further Zeta development", - "test sustained-load and long-horizon state behavior after the architecture and fallback are executable and the evaluation contract is frozen" + "test sustained-load and long-horizon state behavior through the explicit target/fallback runtime boundary" ], "next_actions": [ { - "action": "build the intended PTCNA architecture faithfully under PTCNA-local provenance", - "owner": "The-Interdependency/ptcna", - "dependency": "repository-owned implementation contracts only; upstream evidence and simpler baselines do not grant permission to construct" - }, - { - "action": "build and independently verify a dependable simpler fallback behind the same explicit task boundary", - "owner": "The-Interdependency/ptcna", - "dependency": "the fallback must remain separately identified and must not silently replace, redefine, or be reported as PTCNA" - }, - { - "action": "preregister the critical 'does it work?' evaluation after the target and fallback are sufficiently executable and before outcome inspection", + "action": "preregister the critical 'does it work?' evaluation with EvaluationPlan before outcome inspection", "owner": "The-Interdependency/ptcna", - "dependency": "freeze workload, comparator, metric and aggregation, threshold, resource bounds, stopping rules, failure propagation, and evidence-receipt requirements" + "dependency": "requires a representative labeled workload plus externally justified training, reward, accuracy, comparator-deficit, repetition, resource, and backend-error thresholds; construction remains permitted regardless" }, { "action": "record the terminal result before repair or criterion change", @@ -163,6 +163,8 @@ "historical_stack_manifest": "docs/work-graphs/ptcna-0.1.1-inputs.json", "system_overview": "README.md", "architecture": "docs/architecture.md", + "runtime_boundary": "ptcna/runtime.py", + "frozen_evaluation": "ptcna/evaluation.py", "neural_runtime": "ptcna/neural/pcna.py", "ucns_boundary": "ptcna/ucns_integration.py", "external_measurement_adapter": "ptcna/neural/zeta.py", @@ -171,8 +173,8 @@ "hmmm": [ "the exact PTCNA-specific UCNS producer profile and receipt for any structure later claimed as UCNS-produced", "whether the constructed PTCNA architecture works under the frozen representative evaluation", - "the exact workload, comparator, metric, aggregation, threshold, resource bounds, stopping rules, and failure propagation for that evaluation", - "the exact dependable fallback implementation and shared task-interface identity", + "the exact representative workload and externally justified training epochs, reward, target threshold, comparator-deficit allowance, repetitions, resource bounds, and backend-error status for the implemented evaluation API", + "whether the implemented hashed-linear fallback preserves useful operation on that representative workload", "whether the current ring sizes, heptagram propagation, prime constants, and fixed ring weights contain irreducible useful structure or historical accident", "the authority boundary and migration path between PTCNA's embedded ZetaEngine and The-Interdependency/zfae", "sustained-load behavior across the complete four-layer seam", diff --git a/ptcna/__init__.py b/ptcna/__init__.py index 3fd39b0..ee799e2 100644 --- a/ptcna/__init__.py +++ b/ptcna/__init__.py @@ -1,4 +1,4 @@ -# ratios: loc_comments=22:12 imports_exports=2:1 calls_definitions=1:0 +# ratios: loc_comments=31:51 imports_exports=4:1 calls_definitions=1:0 """PTCNA — Prime Tensor Circled Neural Architecture. One architecture, four layers. Each layer's tensors divide into the next; every @@ -26,6 +26,50 @@ require_ucns_integration, ucns_integration_status, ) +from .runtime import HashedLinearFallback, PTCNAEngine, PTCNARuntime +from .evaluation import EvaluationCase, EvaluationPlan, EvaluationReceipt, evaluate + +# === MODULE_BUILD === +# id: ptcna_package_surface +# module_name: package surface +# module_kind: adapter +# summary: exposes the four layers, explicit runtime boundary, dependable fallback, and frozen evaluation types from the package root +# owner: Erin Spencer +# public_surface: neural, circle, seed, core, PTCNAEngine, HashedLinearFallback, PTCNARuntime, EvaluationCase, EvaluationPlan, EvaluationReceipt, evaluate, UCNS integration status types +# internal_surface: none +# auth_boundary: none +# storage_boundary: none +# network_boundary: none +# user_data_boundary: none +# admin_only: false +# tests: ptcna/tests/test_runtime.py +# rollout: imported through ptcna +# rollback: remove root re-exports while retaining module-qualified imports +# requires: ptcna_runtime_boundary, ptcna_frozen_evaluation, ptcna_ucns_integration +# since: unreleased +# unresolved: none +# === END MODULE_BUILD === + +# === CONTRACTS === +# id: ptcna_root_exports_runtime_boundary +# given: a caller imports ptcna +# then: the experimental engine, distinct fallback, attributed runtime, frozen evaluation types, and evaluator are available without importing deprecated service surfaces +# class: compatibility +# === END CONTRACTS === + +# === BOUNDARIES === +# id: ptcna_package_import_boundary +# summary: imports local package definitions without constructing engines or performing persistence, network, authentication, user-data, or administrative effects +# auth_boundary: none +# storage_boundary: none +# network_boundary: none +# user_data_boundary: none +# admin_only: false +# pii: none +# secrets: none +# owner: Erin Spencer +# since: unreleased +# === END BOUNDARIES === __all__ = [ "neural", @@ -37,6 +81,13 @@ "UCNSIntegrationSuspended", "ucns_integration_status", "require_ucns_integration", + "PTCNAEngine", + "HashedLinearFallback", + "PTCNARuntime", + "EvaluationCase", + "EvaluationPlan", + "EvaluationReceipt", + "evaluate", "__version__", ] -# ratios: loc_comments=22:12 imports_exports=2:1 calls_definitions=1:0 +# ratios: loc_comments=31:51 imports_exports=4:1 calls_definitions=1:0 diff --git a/ptcna/evaluation.py b/ptcna/evaluation.py new file mode 100644 index 0000000..1298813 --- /dev/null +++ b/ptcna/evaluation.py @@ -0,0 +1,463 @@ +# ratios: loc_comments=355:71 imports_exports=10:5 calls_definitions=87:11 +"""Frozen target-versus-fallback evaluation and immutable verdict receipt. + +Usage: + + from ptcna.evaluation import EvaluationCase, EvaluationPlan, evaluate + + plan = EvaluationPlan( + plan_id="representative-workload-v1", + workload=(EvaluationCase("case-1", "input", "phi"),), + minimum_target_accuracy=0.80, + maximum_target_deficit_vs_fallback=0.00, + training_epochs=3, + reward_outcome=1.0, + repetitions=3, + max_training_steps=9, + max_case_evaluations=3, + max_seconds=30.0, + backend_error_status="FALSIFIED", + ) + receipt = evaluate(plan) + +Create and preserve the plan plus ``plan.digest`` before running it. This +module supplies a verdict mechanism; it does not ship a supposedly +representative workload and therefore does not claim PTCNA works. +""" +from __future__ import annotations + +import hashlib +import json +import math +import time +from dataclasses import dataclass +from typing import Any, Callable, Literal + +from .neural import WINNER_RINGS +from .runtime import ( + FALLBACK_BACKEND, + PTCNA_BACKEND, + HashedLinearFallback, + InferenceBackend, + PTCNAEngine, +) + +# === MODULE_BUILD === +# id: ptcna_frozen_evaluation +# module_name: evaluation +# module_kind: experiment +# summary: freezes the workload, training schedule, comparator, metric, thresholds, limits, stopping rule, failure propagation, and evidence receipt before target-versus-fallback execution +# owner: Erin Spencer +# public_surface: EvaluationCase, EvaluationPlan, EvaluationReceipt, evaluate, FALSIFIED, SURVIVED_NOT_PROVED, UNRESOLVED +# internal_surface: _receipt +# auth_boundary: none +# storage_boundary: none +# network_boundary: none +# user_data_boundary: none +# admin_only: false +# tests: ptcna/tests/test_evaluation.py +# rollout: caller supplies a preserved representative EvaluationPlan before execution +# rollback: remove evaluation exports without changing target or fallback runtime behavior +# requires: ptcna_runtime_boundary +# since: unreleased +# unresolved: representative workload identity and externally justified thresholds +# === END MODULE_BUILD === + +# === CONTRACTS === +# id: ptcna_evaluation_plan_freezes_verdict_inputs +# given: an EvaluationPlan is constructed +# then: workload, training schedule, comparator identities, metric, aggregation, thresholds, resource bounds, stopping rule, and failure propagation are immutable and covered by one deterministic digest +# class: evidence +# +# id: ptcna_evaluation_verdict_uses_frozen_thresholds +# given: target and fallback complete the frozen workload +# then: training occurs before scoring and the terminal verdict is FALSIFIED or SURVIVED — not proved using only the plan's post-training accuracy and comparator-deficit thresholds +# class: evidence +# +# id: ptcna_evaluation_propagates_backend_failure +# given: either backend errors before completing the frozen workload +# then: evaluation stops and records the plan's preselected backend_error_status before any repair or criterion change +# class: evidence +# === END CONTRACTS === + +# === BOUNDARIES === +# id: ptcna_evaluation_local_boundary +# summary: executes caller-supplied in-process backends and returns an in-memory receipt without persistence, network, authentication, user-data, or administrative effects +# auth_boundary: none +# storage_boundary: none +# network_boundary: none +# user_data_boundary: none +# admin_only: false +# pii: none +# secrets: none +# owner: Erin Spencer +# since: unreleased +# === END BOUNDARIES === + +FALSIFIED = "FALSIFIED" +SURVIVED_NOT_PROVED = "SURVIVED — not proved" +UNRESOLVED = "UNRESOLVED" +TerminalStatus = Literal["FALSIFIED", "SURVIVED — not proved", "UNRESOLVED"] + + +@dataclass(frozen=True) +class EvaluationCase: + case_id: str + text: str + expected_winner: str + + def __post_init__(self) -> None: + if not all( + isinstance(value, str) + for value in (self.case_id, self.text, self.expected_winner) + ): + raise TypeError("case_id, text, and expected_winner must be strings") + if not self.case_id.strip(): + raise ValueError("case_id must be non-empty") + if not self.text.strip(): + raise ValueError("case text must be non-empty") + if self.expected_winner not in WINNER_RINGS: + raise ValueError(f"expected_winner must be one of {tuple(WINNER_RINGS)}") + + def to_dict(self) -> dict[str, str]: + return { + "case_id": self.case_id, + "text": self.text, + "expected_winner": self.expected_winner, + } + + +@dataclass(frozen=True) +class EvaluationPlan: + plan_id: str + workload: tuple[EvaluationCase, ...] + minimum_target_accuracy: float + maximum_target_deficit_vs_fallback: float + training_epochs: int + reward_outcome: float + repetitions: int + max_training_steps: int + max_case_evaluations: int + max_seconds: float + backend_error_status: Literal["FALSIFIED", "UNRESOLVED"] + target_backend: str = PTCNA_BACKEND + comparator_backend: str = FALLBACK_BACKEND + metric: str = "post_training_winner_accuracy" + aggregation: str = "micro_mean" + stopping_rule: str = "complete_or_first_backend_error_or_resource_limit" + resource_limit_status: Literal["UNRESOLVED"] = UNRESOLVED + + def __post_init__(self) -> None: + if not isinstance(self.plan_id, str): + raise TypeError("plan_id must be a string") + if not self.plan_id.strip(): + raise ValueError("plan_id must be non-empty") + if not isinstance(self.workload, tuple): + object.__setattr__(self, "workload", tuple(self.workload)) + if not self.workload: + raise ValueError("workload must contain at least one case") + if not all(isinstance(case, EvaluationCase) for case in self.workload): + raise TypeError("workload entries must be EvaluationCase instances") + case_ids = [case.case_id for case in self.workload] + if len(case_ids) != len(set(case_ids)): + raise ValueError("workload case_id values must be unique") + for field_name in ( + "minimum_target_accuracy", + "maximum_target_deficit_vs_fallback", + ): + value = float(getattr(self, field_name)) + if not math.isfinite(value) or not 0.0 <= value <= 1.0: + raise ValueError(f"{field_name} must be finite and within [0, 1]") + if not isinstance(self.training_epochs, int) or isinstance( + self.training_epochs, bool + ): + raise TypeError("training_epochs must be an integer") + if self.training_epochs < 0: + raise ValueError("training_epochs must be non-negative") + if not math.isfinite(self.reward_outcome) or not -1.0 <= self.reward_outcome <= 1.0: + raise ValueError("reward_outcome must be finite and within [-1, 1]") + if not isinstance(self.repetitions, int) or isinstance(self.repetitions, bool): + raise TypeError("repetitions must be an integer") + if self.repetitions <= 0: + raise ValueError("repetitions must be positive") + required_training = ( + len(self.workload) * self.training_epochs * self.repetitions + ) + if not isinstance(self.max_training_steps, int) or isinstance( + self.max_training_steps, bool + ): + raise TypeError("max_training_steps must be an integer") + if self.max_training_steps < required_training: + raise ValueError( + "max_training_steps must cover the frozen workload, epochs, and repetitions" + ) + required = len(self.workload) * self.repetitions + if not isinstance(self.max_case_evaluations, int) or isinstance( + self.max_case_evaluations, bool + ): + raise TypeError("max_case_evaluations must be an integer") + if self.max_case_evaluations < required: + raise ValueError( + "max_case_evaluations must cover the frozen workload and repetitions" + ) + if not math.isfinite(self.max_seconds) or self.max_seconds <= 0.0: + raise ValueError("max_seconds must be finite and positive") + if self.backend_error_status not in {FALSIFIED, UNRESOLVED}: + raise ValueError("backend_error_status must be FALSIFIED or UNRESOLVED") + if self.target_backend == self.comparator_backend: + raise ValueError("target and comparator backend identities must differ") + if ( + self.metric != "post_training_winner_accuracy" + or self.aggregation != "micro_mean" + ): + raise ValueError( + "only post_training_winner_accuracy with micro_mean is implemented" + ) + if self.stopping_rule != "complete_or_first_backend_error_or_resource_limit": + raise ValueError("unsupported stopping_rule") + if self.resource_limit_status != UNRESOLVED: + raise ValueError("resource_limit_status must be UNRESOLVED") + + def to_dict(self) -> dict[str, Any]: + return { + "plan_id": self.plan_id, + "workload": [case.to_dict() for case in self.workload], + "target_backend": self.target_backend, + "comparator_backend": self.comparator_backend, + "metric": self.metric, + "aggregation": self.aggregation, + "minimum_target_accuracy": self.minimum_target_accuracy, + "maximum_target_deficit_vs_fallback": ( + self.maximum_target_deficit_vs_fallback + ), + "training_epochs": self.training_epochs, + "reward_outcome": self.reward_outcome, + "repetitions": self.repetitions, + "max_training_steps": self.max_training_steps, + "max_case_evaluations": self.max_case_evaluations, + "max_seconds": self.max_seconds, + "stopping_rule": self.stopping_rule, + "backend_error_status": self.backend_error_status, + "resource_limit_status": self.resource_limit_status, + } + + @property + def digest(self) -> str: + encoded = json.dumps( + self.to_dict(), sort_keys=True, separators=(",", ":"), ensure_ascii=False + ).encode("utf-8") + return hashlib.sha256(encoded).hexdigest() + + +@dataclass(frozen=True) +class EvaluationReceipt: + plan_id: str + plan_digest: str + status: TerminalStatus + target_backend: str + comparator_backend: str + target_accuracy: float | None + comparator_accuracy: float | None + target_deficit_vs_fallback: float | None + training_steps: int + case_evaluations: int + duration_ms: float + failure_reason: str | None + + def to_dict(self) -> dict[str, Any]: + return { + "plan_id": self.plan_id, + "plan_digest": self.plan_digest, + "status": self.status, + "target_backend": self.target_backend, + "comparator_backend": self.comparator_backend, + "target_accuracy": self.target_accuracy, + "comparator_accuracy": self.comparator_accuracy, + "target_deficit_vs_fallback": self.target_deficit_vs_fallback, + "training_steps": self.training_steps, + "case_evaluations": self.case_evaluations, + "duration_ms": self.duration_ms, + "failure_reason": self.failure_reason, + } + + +BackendFactory = Callable[[], InferenceBackend] + + +def _receipt( + plan: EvaluationPlan, + started: float, + *, + status: TerminalStatus, + training_steps: int, + case_evaluations: int, + target_accuracy: float | None = None, + comparator_accuracy: float | None = None, + failure_reason: str | None = None, +) -> EvaluationReceipt: + deficit = None + if target_accuracy is not None and comparator_accuracy is not None: + deficit = comparator_accuracy - target_accuracy + return EvaluationReceipt( + plan_id=plan.plan_id, + plan_digest=plan.digest, + status=status, + target_backend=plan.target_backend, + comparator_backend=plan.comparator_backend, + target_accuracy=target_accuracy, + comparator_accuracy=comparator_accuracy, + target_deficit_vs_fallback=deficit, + training_steps=training_steps, + case_evaluations=case_evaluations, + duration_ms=round((time.perf_counter() - started) * 1000.0, 3), + failure_reason=failure_reason, + ) + + +def evaluate( + plan: EvaluationPlan, + *, + target_factory: BackendFactory = PTCNAEngine, + comparator_factory: BackendFactory = HashedLinearFallback, +) -> EvaluationReceipt: + """Execute only the already-frozen plan and return its terminal receipt.""" + + started = time.perf_counter() + target_correct = 0 + comparator_correct = 0 + training_steps = 0 + case_evaluations = 0 + + for _ in range(plan.repetitions): + try: + target = target_factory() + comparator = comparator_factory() + except Exception as exc: + return _receipt( + plan, + started, + status=UNRESOLVED, + training_steps=training_steps, + case_evaluations=case_evaluations, + failure_reason=f"backend_factory:{type(exc).__name__}", + ) + if getattr(target, "identity", None) != plan.target_backend: + return _receipt( + plan, + started, + status=UNRESOLVED, + training_steps=training_steps, + case_evaluations=case_evaluations, + failure_reason="target_backend_identity_mismatch", + ) + if getattr(comparator, "identity", None) != plan.comparator_backend: + return _receipt( + plan, + started, + status=UNRESOLVED, + training_steps=training_steps, + case_evaluations=case_evaluations, + failure_reason="comparator_backend_identity_mismatch", + ) + + for _ in range(plan.training_epochs): + for case in plan.workload: + if training_steps >= plan.max_training_steps: + return _receipt( + plan, + started, + status=plan.resource_limit_status, + training_steps=training_steps, + case_evaluations=case_evaluations, + failure_reason="max_training_steps", + ) + if time.perf_counter() - started > plan.max_seconds: + return _receipt( + plan, + started, + status=plan.resource_limit_status, + training_steps=training_steps, + case_evaluations=case_evaluations, + failure_reason="max_seconds", + ) + try: + target.infer(case.text) + comparator.infer(case.text) + target.reward(case.expected_winner, plan.reward_outcome) + comparator.reward(case.expected_winner, plan.reward_outcome) + except Exception as exc: + return _receipt( + plan, + started, + status=plan.backend_error_status, + training_steps=training_steps, + case_evaluations=case_evaluations, + failure_reason=f"backend_error:{type(exc).__name__}", + ) + training_steps += 1 + + for case in plan.workload: + if case_evaluations >= plan.max_case_evaluations: + return _receipt( + plan, + started, + status=plan.resource_limit_status, + training_steps=training_steps, + case_evaluations=case_evaluations, + failure_reason="max_case_evaluations", + ) + if time.perf_counter() - started > plan.max_seconds: + return _receipt( + plan, + started, + status=plan.resource_limit_status, + training_steps=training_steps, + case_evaluations=case_evaluations, + failure_reason="max_seconds", + ) + try: + target_result = target.infer(case.text) + comparator_result = comparator.infer(case.text) + target_winner = target_result.get("winner") + comparator_winner = comparator_result.get("winner") + except Exception as exc: + return _receipt( + plan, + started, + status=plan.backend_error_status, + training_steps=training_steps, + case_evaluations=case_evaluations, + failure_reason=f"backend_error:{type(exc).__name__}", + ) + target_correct += target_winner == case.expected_winner + comparator_correct += comparator_winner == case.expected_winner + case_evaluations += 1 + + target_accuracy = target_correct / case_evaluations + comparator_accuracy = comparator_correct / case_evaluations + survived = ( + target_accuracy >= plan.minimum_target_accuracy + and target_accuracy + plan.maximum_target_deficit_vs_fallback + >= comparator_accuracy + ) + return _receipt( + plan, + started, + status=SURVIVED_NOT_PROVED if survived else FALSIFIED, + training_steps=training_steps, + case_evaluations=case_evaluations, + target_accuracy=target_accuracy, + comparator_accuracy=comparator_accuracy, + ) + + +__all__ = [ + "FALSIFIED", + "SURVIVED_NOT_PROVED", + "UNRESOLVED", + "EvaluationCase", + "EvaluationPlan", + "EvaluationReceipt", + "evaluate", +] +# ratios: loc_comments=355:71 imports_exports=10:5 calls_definitions=87:11 diff --git a/ptcna/neural/main.py b/ptcna/neural/main.py deleted file mode 100644 index 50c3110..0000000 --- a/ptcna/neural/main.py +++ /dev/null @@ -1,183 +0,0 @@ -# ratios: loc_comments=100:46 imports_exports=9:7 calls_definitions=40:12 -""" -FastAPI seed runner for PCNA. This file provides a minimal runnable seed -process that can act as compute/meta/global/sentinel. It is intentionally -lightweight and suitable for local testing. - -Environment configuration: - - SEED_ID: int (default 0) - - ROLE: one of compute|meta|sentinel|global (default compute) - -The networking layer here is a minimal placeholder using aiohttp. In a real -deployment you'd wire actual DNS/ports mapping per-seed. -""" - -# === MODULE_BUILD === -# id: pcna_core_main -# module_name: main -# module_kind: service -# summary: Minimal FastAPI seed-runner process (compute/meta/sentinel/global) exposing health/topology/receive_delta routes with an aiohttp networking placeholder. -# owner: Erin Spencer -# public_surface: app, PCNASeed, health, topology, receive_delta, startup, shutdown, tick_loop -# internal_surface: seed_instance -# auth_boundary: none -# storage_boundary: none -# network_boundary: external -# user_data_boundary: none -# admin_only: false -# tests: hmmm -# rollout: default_enabled -# rollback: do not launch this process; use root-level main.py seed runner instead -# requires: pcna_topology, pcna_tensor_engine -# since: 2026-06-02 -# unresolved: BROKEN alt entry point — imports from non-existent src.core.* (do not use per CLAUDE.md) -# === END MODULE_BUILD === - -import os -import asyncio -from typing import Dict, Any, Optional -import logging - -from fastapi import FastAPI, BackgroundTasks -import uvicorn -import aiohttp - -from src.core.topology import PCNATopology, SeedRole -from src.core.tensor_engine import TensorState, MarkovRecursion - -logger = logging.getLogger("pcna") -logging.basicConfig(level=logging.INFO) - -app = FastAPI(title="PCNA Seed") - -seed_instance: Optional["PCNASeed"] = None - - -class PCNASeed: - def __init__(self, seed_id: int, role: SeedRole): - self.seed_id = seed_id - self.role = role - self.topology = PCNATopology() - self.state: Optional[TensorState] = None - self.tick = 0 - self._client = aiohttp.ClientSession() - - if role == SeedRole.COMPUTE: - # Create a small default tensor for local testing/demo. - actor = [0] # simple single-dim actor/time/context for demo - time = [0] - metric = (1.0 * (np := __import__("numpy"))).ones((1,)) # single-value metric - context = [0] - self.state = TensorState(actor=np.array(actor), time=np.array(time), metric=metric, context=np.array(context)) - self.tensor_engine = MarkovRecursion() - logger.info(f"Initialized compute seed {seed_id} with trivial state") - - async def process_tick(self): - self.tick += 1 - logger.debug(f"Seed {self.seed_id} processing tick {self.tick}") - - if self.role == SeedRole.COMPUTE: - await self._compute_tick() - # meta/sentinel/global roles could be handled here with specific logic - - async def _compute_tick(self): - # Example compute operations: compute injected/resolved (dummy here) - injected = self.state.metric * 0.01 # small injected - resolved = self.state.metric * 0.009 # slightly different to demonstrate conservation - new_state = self.tensor_engine.update(self.state, injected, resolved) - self.state = new_state - - # send deltas to neighbors (using global neighbor ids, convert to URLs in your deployment) - seed_info = self.topology.seeds.get(self.seed_id) - if seed_info and seed_info.neighbors: - for neighbor_id in seed_info.neighbors: - # in local testing this will likely fail unless neighbor URL mapping is provided - await self._send_to_neighbor(neighbor_id, {"from": self.seed_id, "tick": self.tick}) - - async def _send_to_neighbor(self, neighbor_id: int, payload: Dict[str, Any]): - """ - Simple async HTTP POST to a neighbor. This function assumes a mapping - from neighbor_id -> host:port which is environment-specific. - For local testing, you can set SEED_URL_ environment variables, - e.g. SEED_URL_6=http://localhost:8001 - """ - env_var = f"SEED_URL_{neighbor_id}" - url = os.getenv(env_var) - if not url: - # nothing configured for neighbor, skip - logger.debug(f"No URL configured for neighbor {neighbor_id} (env {env_var}), skipping send") - return - - try: - async with self._client.post(f"{url}/receive_delta", json=payload, timeout=2) as resp: - logger.debug(f"Sent delta to {neighbor_id} ({url}), status {resp.status}") - except Exception as exc: - logger.warning(f"Failed to send to neighbor {neighbor_id} at {url}: {exc}") - - async def close(self): - await self._client.close() - - -async def tick_loop(): - while True: - try: - if seed_instance: - await seed_instance.process_tick() - await asyncio.sleep(1.0) - except asyncio.CancelledError: - break - except Exception as exc: - logger.exception(f"tick loop error: {exc}") - await asyncio.sleep(1.0) - - -@app.on_event("startup") -async def startup(): - global seed_instance - seed_id = int(os.getenv("SEED_ID", "0")) - role_raw = os.getenv("ROLE", "compute").lower() - try: - role = SeedRole(role_raw) - except Exception: - # fallback if value is 'compute', 'meta', etc. - role = SeedRole.COMPUTE - - seed_instance = PCNASeed(seed_id=seed_id, role=role) - - # launch tick loop - asyncio.create_task(tick_loop()) - logger.info(f"Seed {seed_id} (role={role.value}) started") - - -@app.on_event("shutdown") -async def shutdown(): - if seed_instance: - await seed_instance.close() - - -@app.get("/health") -async def health(): - if not seed_instance: - return {"status": "starting"} - return {"status": "healthy", "seed_id": seed_instance.seed_id, "role": seed_instance.role.value} - - -@app.get("/topology") -async def topology(): - if not seed_instance: - return {} - return seed_instance.topology.to_dict() - - -@app.post("/receive_delta") -async def receive_delta(delta: Dict): - # In a real system, we'd validate and apply the delta to a pending buffer. - logger.info(f"Received delta at seed {seed_instance.seed_id if seed_instance else 'unknown'}: {delta}") - return {"status": "received"} - - -if __name__ == "__main__": - # Useful for local development: honor PORT env var and SEED_ID/ROLE - port = int(os.getenv("PORT", os.getenv("PORT0", "8000"))) - uvicorn.run("src.main:app", host="0.0.0.0", port=port, log_level="info") -# ratios: loc_comments=100:46 imports_exports=9:7 calls_definitions=40:12 diff --git a/ptcna/runtime.py b/ptcna/runtime.py new file mode 100644 index 0000000..187dbbf --- /dev/null +++ b/ptcna/runtime.py @@ -0,0 +1,363 @@ +# ratios: loc_comments=234:78 imports_exports=8:5 calls_definitions=57:23 +"""Explicit runtime boundary for the experimental PTCNA path and fallback. + +Usage: + + from ptcna.runtime import PTCNARuntime + + runtime = PTCNARuntime() + target = runtime.infer("bounded question") + fallback = runtime.infer("bounded question", backend="fallback") + +The target path constructs the repository's full four-layer architecture. The +fallback is a deterministic hashed linear learner behind the same +``infer``/``reward`` task surface. A target failure raises by default. Callers +must set ``fallback_on_error=True`` to continue through the fallback, and the +returned receipt always names the backend actually used. +""" +from __future__ import annotations + +import hashlib +import math +from typing import Any, Literal, Mapping, Protocol + +import numpy as np + +from .core.prime_core import Core, CoreSpec, build_core +from .neural import PCNAEngine, WINNER_RINGS + +# === MODULE_BUILD === +# id: ptcna_runtime_boundary +# module_name: runtime +# module_kind: engine +# summary: exposes the intended four-layer PTCNA path and a distinct dependable fallback behind one attributed task interface +# owner: Erin Spencer +# public_surface: PTCNAEngine, HashedLinearFallback, PTCNARuntime, InferenceBackend, PTCNA_BACKEND, FALLBACK_BACKEND +# internal_surface: _validate_text, _validate_reward, _attach_route +# auth_boundary: none +# storage_boundary: none +# network_boundary: none +# user_data_boundary: none +# admin_only: false +# tests: ptcna/tests/test_runtime.py +# rollout: explicit public API; target selected by default and fallback selected or enabled by the caller +# rollback: remove runtime exports while preserving the existing layer modules and PCNAEngine +# requires: pcna_pcna, ptcna_prime_core_composition +# since: unreleased +# unresolved: representative task workload and whether either backend is useful under it +# === END MODULE_BUILD === + +# === CONTRACTS === +# id: ptcna_target_reports_four_live_layers +# given: non-empty text is inferred through PTCNAEngine +# then: the receipt identifies the experimental PTCNA backend and reports neural, circle, seed, and core layer state without transferring gradients to structural layers +# class: correctness +# +# id: ptcna_fallback_is_distinct_and_deterministic +# given: identical text and fresh HashedLinearFallback instances +# then: both produce the same bounded prediction under a fallback identity that is never labeled PTCNA +# class: correctness +# +# id: ptcna_fallback_reward_changes_selected_score +# given: the fallback infers text and receives a positive bounded reward for the selected winner +# then: a second inference of the same text gives that winner a strictly greater linear score +# class: correctness +# +# id: ptcna_failover_is_explicit_and_attributed +# given: the target raises during inference +# then: PTCNARuntime raises by default and uses the fallback only when explicitly enabled while recording the target failure and actual backend +# class: safety +# +# id: ptcna_reward_follows_backend_receipt +# given: a reward is applied to an inference receipt +# then: only the backend named by backend_used receives the reward +# class: safety +# === END CONTRACTS === + +# === BOUNDARIES === +# id: ptcna_runtime_local_boundary +# summary: performs deterministic in-process inference and learning with no authentication, persistence, network, user-data, or administrative effect +# auth_boundary: none +# storage_boundary: none +# network_boundary: none +# user_data_boundary: none +# admin_only: false +# pii: none +# secrets: none +# owner: Erin Spencer +# since: unreleased +# === END BOUNDARIES === + +PTCNA_BACKEND = "ptcna.experimental.v1" +FALLBACK_BACKEND = "fallback.hashed-linear.v1" +BackendChoice = Literal["ptcna", "fallback"] + + +class InferenceBackend(Protocol): + """Shared task surface implemented independently by target and fallback.""" + + identity: str + + def infer(self, text: str) -> dict[str, Any]: ... + + def reward(self, winner: str, outcome: float) -> dict[str, Any]: ... + + def state(self) -> dict[str, Any]: ... + + +def _validate_text(text: str) -> None: + if not isinstance(text, str) or not text.strip(): + raise ValueError("text must be a non-empty string") + + +def _validate_reward(winner: str, outcome: float) -> float: + if winner not in WINNER_RINGS: + raise ValueError(f"winner must be one of {tuple(WINNER_RINGS)}") + outcome = float(outcome) + if not math.isfinite(outcome) or not -1.0 <= outcome <= 1.0: + raise ValueError("outcome must be finite and within [-1, 1]") + return outcome + + +class PTCNAEngine: + """Target backend joining the live neural engine to the full local core.""" + + identity = PTCNA_BACKEND + + def __init__(self, phases: int = 7, core_spec: CoreSpec | None = None) -> None: + self.neural = PCNAEngine(phases=phases) + self.core: Core = build_core(core_spec if core_spec is not None else CoreSpec()) + self._core_state = { + "requires_grad": self.core.requires_grad, + "seed_count": self.core.spec.seed_count, + "circles_per_seed": self.core.spec.circles_per_seed, + "tensors_per_circle": self.core.spec.tensors_per_circle, + "tensor_dim": self.core.spec.tensor_dim, + "tensor_leaves": self.core.spec.tensor_leaves, + "param_positions": self.core.spec.param_count, + "ucns_state": self.core.ucns_status.state.value, + "provenance": "ptcna-local", + } + + def infer(self, text: str) -> dict[str, Any]: + """Run the experimental architecture and return an attributed receipt.""" + + _validate_text(text) + neural_receipt = self.neural.infer(text) + result = dict(neural_receipt) + result.update( + { + "architecture": "ptcna", + "backend": self.identity, + "layers": { + "neural": { + "requires_grad": True, + "engine": "PCNAEngine", + "infer_index": neural_receipt["infer_index"], + }, + "circle": { + "requires_grad": False, + **neural_receipt["step5_circle"], + }, + "seed": { + "requires_grad": False, + **neural_receipt["step4_seed"], + }, + "core": dict(self._core_state), + }, + } + ) + return result + + def reward(self, winner: str, outcome: float) -> dict[str, Any]: + """Reward the neural owner; structural layers remain non-differentiating.""" + + outcome = _validate_reward(winner, outcome) + result = dict(self.neural.reward(winner, outcome)) + result["backend"] = self.identity + result["structural_layers_nudged"] = False + return result + + def state(self) -> dict[str, Any]: + return { + "backend": self.identity, + "architecture": "ptcna", + "neural": self.neural.state(), + "core": dict(self._core_state), + } + + +class HashedLinearFallback: + """Deterministic in-memory online learner used only as the fallback path.""" + + identity = FALLBACK_BACKEND + feature_count = 53 + + def __init__(self, learning_rate: float = 0.1) -> None: + learning_rate = float(learning_rate) + if not math.isfinite(learning_rate) or learning_rate <= 0.0: + raise ValueError("learning_rate must be finite and positive") + self.learning_rate = learning_rate + self._weights = np.zeros( + (len(WINNER_RINGS), self.feature_count), dtype=np.float64 + ) + self._last_features: np.ndarray | None = None + self.infer_count = 0 + self.reward_count = 0 + + @classmethod + def _features(cls, text: str) -> np.ndarray: + digest = hashlib.sha512(text.encode("utf-8")).digest() + values = np.frombuffer(digest, dtype=np.uint8)[: cls.feature_count] + features = (values.astype(np.float64) - 127.5) / 127.5 + norm = float(np.linalg.norm(features)) + return features / norm if norm else features + + def infer(self, text: str) -> dict[str, Any]: + _validate_text(text) + features = self._features(text) + scores = self._weights @ features + shifted = scores - float(scores.max()) + probabilities = np.exp(shifted) + probabilities /= float(probabilities.sum()) + winner_index = int(np.argmax(probabilities)) + self._last_features = features + self.infer_count += 1 + return { + "step": "fallback_infer", + "architecture": "hashed_linear_fallback", + "backend": self.identity, + "infer_index": self.infer_count, + "winner": WINNER_RINGS[winner_index], + "confidence": round(float(probabilities[winner_index]), 6), + "scores": { + label: round(float(scores[index]), 6) + for index, label in enumerate(WINNER_RINGS) + }, + } + + def reward(self, winner: str, outcome: float) -> dict[str, Any]: + outcome = _validate_reward(winner, outcome) + if self._last_features is None: + raise RuntimeError("fallback reward requires a preceding inference") + winner_index = WINNER_RINGS.index(winner) + self._weights[winner_index] += ( + self.learning_rate * outcome * self._last_features + ) + self.reward_count += 1 + return { + "step": "fallback_reward", + "backend": self.identity, + "reward_index": self.reward_count, + "winner": winner, + "outcome": outcome, + } + + def state(self) -> dict[str, Any]: + return { + "backend": self.identity, + "feature_count": self.feature_count, + "learning_rate": self.learning_rate, + "infer_count": self.infer_count, + "reward_count": self.reward_count, + "weights_digest": hashlib.sha256(self._weights.tobytes()).hexdigest(), + } + + +def _attach_route( + result: Mapping[str, Any], + *, + requested_backend: BackendChoice, + backend_used: str, + routing_reason: Literal["requested", "target_failure"], + target_error: str | None = None, +) -> dict[str, Any]: + receipt = dict(result) + receipt.update( + { + "requested_backend": requested_backend, + "backend_used": backend_used, + "fallback_used": backend_used == FALLBACK_BACKEND, + "routing_reason": routing_reason, + "target_error": target_error, + } + ) + return receipt + + +class PTCNARuntime: + """Select target or fallback without hiding which implementation ran.""" + + def __init__( + self, + target: InferenceBackend | None = None, + fallback: InferenceBackend | None = None, + ) -> None: + self.target = target if target is not None else PTCNAEngine() + self.fallback = fallback if fallback is not None else HashedLinearFallback() + + def infer( + self, + text: str, + *, + backend: BackendChoice = "ptcna", + fallback_on_error: bool = False, + ) -> dict[str, Any]: + _validate_text(text) + if backend == "fallback": + return _attach_route( + self.fallback.infer(text), + requested_backend=backend, + backend_used=self.fallback.identity, + routing_reason="requested", + ) + if backend != "ptcna": + raise ValueError("backend must be 'ptcna' or 'fallback'") + try: + result = self.target.infer(text) + except Exception as exc: + if not fallback_on_error: + raise + return _attach_route( + self.fallback.infer(text), + requested_backend=backend, + backend_used=self.fallback.identity, + routing_reason="target_failure", + target_error=type(exc).__name__, + ) + return _attach_route( + result, + requested_backend=backend, + backend_used=self.target.identity, + routing_reason="requested", + ) + + def reward(self, receipt: Mapping[str, Any], outcome: float) -> dict[str, Any]: + """Route reward to the backend recorded by a prior inference receipt.""" + + backend_used = receipt.get("backend_used") + winner = receipt.get("winner") + if not isinstance(winner, str): + raise ValueError("receipt must contain a string winner") + if backend_used == self.target.identity: + return self.target.reward(winner, outcome) + if backend_used == self.fallback.identity: + return self.fallback.reward(winner, outcome) + raise ValueError("receipt backend_used does not match this runtime") + + def state(self) -> dict[str, Any]: + return { + "target": self.target.state(), + "fallback": self.fallback.state(), + } + + +__all__ = [ + "PTCNA_BACKEND", + "FALLBACK_BACKEND", + "InferenceBackend", + "PTCNAEngine", + "HashedLinearFallback", + "PTCNARuntime", +] +# ratios: loc_comments=234:78 imports_exports=8:5 calls_definitions=57:23 diff --git a/ptcna/tests/test_evaluation.py b/ptcna/tests/test_evaluation.py new file mode 100644 index 0000000..b9f19b0 --- /dev/null +++ b/ptcna/tests/test_evaluation.py @@ -0,0 +1,150 @@ +"""Executable evidence for frozen evaluation and terminal verdicts.""" + +from ptcna.evaluation import ( + FALSIFIED, + SURVIVED_NOT_PROVED, + EvaluationCase, + EvaluationPlan, + evaluate, +) +from ptcna.runtime import FALLBACK_BACKEND, PTCNA_BACKEND + +# === CHECKS === +# id: check_ptcna_plan_digest +# proves: ptcna_evaluation_plan_freezes_verdict_inputs +# call: self::test_plan_digest_is_stable_and_criteria_sensitive +# requires: python3 +# timeout: 30 +# mutates: none +# cleanup: none +# +# id: check_ptcna_frozen_verdicts +# proves: ptcna_evaluation_verdict_uses_frozen_thresholds +# call: self::test_frozen_thresholds_produce_survival_and_falsification +# requires: python3 +# timeout: 30 +# mutates: none +# cleanup: none +# +# id: check_ptcna_failure_propagation +# proves: ptcna_evaluation_propagates_backend_failure +# call: self::test_backend_failure_stops_with_preselected_status +# requires: python3 +# timeout: 30 +# mutates: none +# cleanup: none +# === END CHECKS === + + +class _ScriptedBackend: + def __init__(self, identity: str, winners: dict[str, str]) -> None: + self.identity = identity + self._winners = winners + self._last_text = "" + + def infer(self, text: str) -> dict: + self._last_text = text + return {"winner": self._winners[text], "backend": self.identity} + + def reward(self, winner: str, outcome: float) -> dict: + return {"winner": winner, "outcome": outcome, "backend": self.identity} + + def state(self) -> dict: + return {"backend": self.identity} + + +class _ErrorBackend(_ScriptedBackend): + def infer(self, text: str) -> dict: + raise RuntimeError("frozen failure") + + +class _LearningBackend(_ScriptedBackend): + def reward(self, winner: str, outcome: float) -> dict: + self._winners[self._last_text] = winner + return super().reward(winner, outcome) + + +def _plan(**changes) -> EvaluationPlan: + values = { + "plan_id": "fixture-v1", + "workload": ( + EvaluationCase("one", "one", "phi"), + EvaluationCase("two", "two", "psi"), + ), + "minimum_target_accuracy": 1.0, + "maximum_target_deficit_vs_fallback": 0.0, + "training_epochs": 0, + "reward_outcome": 1.0, + "repetitions": 1, + "max_training_steps": 0, + "max_case_evaluations": 2, + "max_seconds": 10.0, + "backend_error_status": FALSIFIED, + } + values.update(changes) + return EvaluationPlan(**values) + + +def test_plan_digest_is_stable_and_criteria_sensitive() -> None: + first = _plan() + second = _plan() + changed = _plan(minimum_target_accuracy=0.5) + assert first.digest == second.digest + assert first.digest != changed.digest + assert first.to_dict()["stopping_rule"] == ( + "complete_or_first_backend_error_or_resource_limit" + ) + + +def test_frozen_thresholds_produce_survival_and_falsification() -> None: + target_correct = lambda: _ScriptedBackend( + PTCNA_BACKEND, {"one": "phi", "two": "psi"} + ) + target_wrong = lambda: _ScriptedBackend( + PTCNA_BACKEND, {"one": "omega", "two": "omega"} + ) + fallback = lambda: _ScriptedBackend( + FALLBACK_BACKEND, {"one": "phi", "two": "psi"} + ) + survived = evaluate( + _plan(), target_factory=target_correct, comparator_factory=fallback + ) + falsified = evaluate( + _plan(), target_factory=target_wrong, comparator_factory=fallback + ) + assert survived.status == SURVIVED_NOT_PROVED + assert survived.target_accuracy == 1.0 + assert falsified.status == FALSIFIED + assert falsified.target_accuracy == 0.0 + assert falsified.comparator_accuracy == 1.0 + + learning_target = lambda: _LearningBackend( + PTCNA_BACKEND, {"one": "omega", "two": "omega"} + ) + learning_fallback = lambda: _LearningBackend( + FALLBACK_BACKEND, {"one": "omega", "two": "omega"} + ) + learned = evaluate( + _plan(training_epochs=1, max_training_steps=2), + target_factory=learning_target, + comparator_factory=learning_fallback, + ) + assert learned.status == SURVIVED_NOT_PROVED + assert learned.training_steps == 2 + assert learned.target_accuracy == 1.0 + + +def test_backend_failure_stops_with_preselected_status() -> None: + target = lambda: _ErrorBackend(PTCNA_BACKEND, {}) + fallback = lambda: _ScriptedBackend( + FALLBACK_BACKEND, {"one": "phi", "two": "psi"} + ) + receipt = evaluate( + _plan(backend_error_status=FALSIFIED), + target_factory=target, + comparator_factory=fallback, + ) + assert receipt.status == FALSIFIED + assert receipt.training_steps == 0 + assert receipt.case_evaluations == 0 + assert receipt.failure_reason == "backend_error:RuntimeError" diff --git a/ptcna/tests/test_runtime.py b/ptcna/tests/test_runtime.py new file mode 100644 index 0000000..1bb13f5 --- /dev/null +++ b/ptcna/tests/test_runtime.py @@ -0,0 +1,134 @@ +"""Executable evidence for explicit target and fallback runtime behavior.""" + +import pytest + +import ptcna +from ptcna.runtime import ( + FALLBACK_BACKEND, + PTCNA_BACKEND, + HashedLinearFallback, + PTCNAEngine, + PTCNARuntime, +) + +# === CHECKS === +# id: check_ptcna_target_four_layers +# proves: ptcna_target_reports_four_live_layers +# call: self::test_target_reports_all_four_live_layers +# requires: python3, numpy +# timeout: 30 +# mutates: none +# cleanup: none +# +# id: check_ptcna_fallback_determinism +# proves: ptcna_fallback_is_distinct_and_deterministic +# call: self::test_fallback_is_deterministic_bounded_and_distinct +# requires: python3, numpy +# timeout: 30 +# mutates: none +# cleanup: none +# +# id: check_ptcna_fallback_reward +# proves: ptcna_fallback_reward_changes_selected_score +# call: self::test_fallback_positive_reward_increases_selected_score +# requires: python3, numpy +# timeout: 30 +# mutates: none +# cleanup: none +# +# id: check_ptcna_explicit_failover +# proves: ptcna_failover_is_explicit_and_attributed +# call: self::test_target_failure_requires_explicit_attributed_failover +# requires: python3, numpy +# timeout: 30 +# mutates: none +# cleanup: none +# +# id: check_ptcna_reward_route +# proves: ptcna_reward_follows_backend_receipt +# call: self::test_reward_follows_the_recorded_backend +# requires: python3, numpy +# timeout: 30 +# mutates: none +# cleanup: none +# +# id: check_ptcna_root_runtime_exports +# proves: ptcna_root_exports_runtime_boundary +# call: self::test_root_exports_runtime_and_evaluation_surface +# requires: python3 +# timeout: 30 +# mutates: none +# cleanup: none +# === END CHECKS === + + +class _FailingTarget: + identity = PTCNA_BACKEND + + def infer(self, text: str) -> dict: + raise RuntimeError("declared test failure") + + def reward(self, winner: str, outcome: float) -> dict: + raise AssertionError("failed target must not receive fallback reward") + + def state(self) -> dict: + return {"backend": self.identity} + + +def test_target_reports_all_four_live_layers() -> None: + engine = PTCNAEngine() + result = engine.infer("four layer receipt") + assert result["backend"] == PTCNA_BACKEND + assert tuple(result["layers"]) == ("neural", "circle", "seed", "core") + assert result["layers"]["neural"]["requires_grad"] is True + for layer in ("circle", "seed", "core"): + assert result["layers"][layer]["requires_grad"] is False + assert result["layers"]["core"]["seed_count"] == 157 + assert result["layers"]["core"]["tensor_leaves"] == 7693 + assert result["layers"]["core"]["param_positions"] == 407729 + + +def test_fallback_is_deterministic_bounded_and_distinct() -> None: + first = HashedLinearFallback().infer("same input") + second = HashedLinearFallback().infer("same input") + assert first["backend"] == FALLBACK_BACKEND + assert first["architecture"] != "ptcna" + assert first["winner"] == second["winner"] + assert first["confidence"] == second["confidence"] + assert 0.0 <= first["confidence"] <= 1.0 + + +def test_fallback_positive_reward_increases_selected_score() -> None: + fallback = HashedLinearFallback() + before = fallback.infer("learn this") + winner = before["winner"] + fallback.reward(winner, 1.0) + after = fallback.infer("learn this") + assert after["scores"][winner] > before["scores"][winner] + + +def test_target_failure_requires_explicit_attributed_failover() -> None: + runtime = PTCNARuntime(target=_FailingTarget()) + with pytest.raises(RuntimeError, match="declared test failure"): + runtime.infer("fail closed") + receipt = runtime.infer("continue explicitly", fallback_on_error=True) + assert receipt["requested_backend"] == "ptcna" + assert receipt["backend_used"] == FALLBACK_BACKEND + assert receipt["fallback_used"] is True + assert receipt["routing_reason"] == "target_failure" + assert receipt["target_error"] == "RuntimeError" + + +def test_reward_follows_the_recorded_backend() -> None: + runtime = PTCNARuntime(target=_FailingTarget()) + receipt = runtime.infer("reward fallback", fallback_on_error=True) + rewarded = runtime.reward(receipt, 1.0) + assert rewarded["backend"] == FALLBACK_BACKEND + assert runtime.fallback.state()["reward_count"] == 1 + + +def test_root_exports_runtime_and_evaluation_surface() -> None: + assert ptcna.PTCNAEngine is PTCNAEngine + assert ptcna.PTCNARuntime is PTCNARuntime + assert ptcna.HashedLinearFallback is HashedLinearFallback + assert callable(ptcna.evaluate) diff --git a/ptcna_msdmd.ts b/ptcna_msdmd.ts index b59fdfd..9d46e76 100644 --- a/ptcna_msdmd.ts +++ b/ptcna_msdmd.ts @@ -2,6 +2,57 @@ import { defineMsdmdCollection } from "./.agents/skills/msdmd/collection"; export default defineMsdmdCollection({ "declarations": [ + { + "block": "BOUNDARIES", + "fields": { + "admin_only": "false", + "auth_boundary": "none", + "network_boundary": "none", + "owner": "Erin Spencer", + "pii": "none", + "secrets": "none", + "since": "unreleased", + "storage_boundary": "none", + "summary": "imports local package definitions without constructing engines or performing persistence, network, authentication, user-data, or administrative effects", + "user_data_boundary": "none" + }, + "file": "ptcna/__init__.py", + "id": "ptcna_package_import_boundary" + }, + { + "block": "CONTRACTS", + "fields": { + "class": "compatibility", + "given": "a caller imports ptcna", + "then": "the experimental engine, distinct fallback, attributed runtime, frozen evaluation types, and evaluator are available without importing deprecated service surfaces" + }, + "file": "ptcna/__init__.py", + "id": "ptcna_root_exports_runtime_boundary" + }, + { + "block": "MODULE_BUILD", + "fields": { + "admin_only": "false", + "auth_boundary": "none", + "internal_surface": "none", + "module_kind": "adapter", + "module_name": "package surface", + "network_boundary": "none", + "owner": "Erin Spencer", + "public_surface": "neural, circle, seed, core, PTCNAEngine, HashedLinearFallback, PTCNARuntime, EvaluationCase, EvaluationPlan, EvaluationReceipt, evaluate, UCNS integration status types", + "requires": "ptcna_runtime_boundary, ptcna_frozen_evaluation, ptcna_ucns_integration", + "rollback": "remove root re-exports while retaining module-qualified imports", + "rollout": "imported through ptcna", + "since": "unreleased", + "storage_boundary": "none", + "summary": "exposes the four layers, explicit runtime boundary, dependable fallback, and frozen evaluation types from the package root", + "tests": "ptcna/tests/test_runtime.py", + "unresolved": "none", + "user_data_boundary": "none" + }, + "file": "ptcna/__init__.py", + "id": "ptcna_package_surface" + }, { "block": "BOUNDARIES", "fields": { @@ -466,6 +517,77 @@ export default defineMsdmdCollection({ "file": "ptcna/core/prime_core/tests/test_ptca_core_stratified.py", "id": "check_prime_core_suspended_ucns" }, + { + "block": "BOUNDARIES", + "fields": { + "admin_only": "false", + "auth_boundary": "none", + "network_boundary": "none", + "owner": "Erin Spencer", + "pii": "none", + "secrets": "none", + "since": "unreleased", + "storage_boundary": "none", + "summary": "executes caller-supplied in-process backends and returns an in-memory receipt without persistence, network, authentication, user-data, or administrative effects", + "user_data_boundary": "none" + }, + "file": "ptcna/evaluation.py", + "id": "ptcna_evaluation_local_boundary" + }, + { + "block": "CONTRACTS", + "fields": { + "class": "evidence", + "given": "an EvaluationPlan is constructed", + "then": "workload, training schedule, comparator identities, metric, aggregation, thresholds, resource bounds, stopping rule, and failure propagation are immutable and covered by one deterministic digest" + }, + "file": "ptcna/evaluation.py", + "id": "ptcna_evaluation_plan_freezes_verdict_inputs" + }, + { + "block": "CONTRACTS", + "fields": { + "class": "evidence", + "given": "either backend errors before completing the frozen workload", + "then": "evaluation stops and records the plan's preselected backend_error_status before any repair or criterion change" + }, + "file": "ptcna/evaluation.py", + "id": "ptcna_evaluation_propagates_backend_failure" + }, + { + "block": "CONTRACTS", + "fields": { + "class": "evidence", + "given": "target and fallback complete the frozen workload", + "then": "training occurs before scoring and the terminal verdict is FALSIFIED or SURVIVED \u2014 not proved using only the plan's post-training accuracy and comparator-deficit thresholds" + }, + "file": "ptcna/evaluation.py", + "id": "ptcna_evaluation_verdict_uses_frozen_thresholds" + }, + { + "block": "MODULE_BUILD", + "fields": { + "admin_only": "false", + "auth_boundary": "none", + "internal_surface": "_receipt", + "module_kind": "experiment", + "module_name": "evaluation", + "network_boundary": "none", + "owner": "Erin Spencer", + "public_surface": "EvaluationCase, EvaluationPlan, EvaluationReceipt, evaluate, FALSIFIED, SURVIVED_NOT_PROVED, UNRESOLVED", + "requires": "ptcna_runtime_boundary", + "rollback": "remove evaluation exports without changing target or fallback runtime behavior", + "rollout": "caller supplies a preserved representative EvaluationPlan before execution", + "since": "unreleased", + "storage_boundary": "none", + "summary": "freezes the workload, training schedule, comparator, metric, thresholds, limits, stopping rule, failure propagation, and evidence receipt before target-versus-fallback execution", + "tests": "ptcna/tests/test_evaluation.py", + "unresolved": "representative workload identity and externally justified thresholds", + "user_data_boundary": "none" + }, + "file": "ptcna/evaluation.py", + "id": "ptcna_frozen_evaluation" + }, { "block": "MODULE_BUILD", "fields": { @@ -490,30 +612,6 @@ export default defineMsdmdCollection({ "file": "ptcna/neural/helix_vis.py", "id": "pcna_helix_vis" }, - { - "block": "MODULE_BUILD", - "fields": { - "admin_only": "false", - "auth_boundary": "none", - "internal_surface": "seed_instance", - "module_kind": "service", - "module_name": "main", - "network_boundary": "external", - "owner": "Erin Spencer", - "public_surface": "app, PCNASeed, health, topology, receive_delta, startup, shutdown, tick_loop", - "requires": "pcna_topology, pcna_tensor_engine", - "rollback": "do not launch this process; use root-level main.py seed runner instead", - "rollout": "default_enabled", - "since": "2026-06-02", - "storage_boundary": "none", - "summary": "Minimal FastAPI seed-runner process (compute/meta/sentinel/global) exposing health/topology/receive_delta routes with an aiohttp networking placeholder.", - "tests": "hmmm", - "unresolved": "BROKEN alt entry point \u2014 imports from non-existent src.core.* (do not use per CLAUDE.md)", - "user_data_boundary": "none" - }, - "file": "ptcna/neural/main.py", - "id": "pcna_core_main" - }, { "block": "MODULE_BUILD", "fields": { @@ -1013,6 +1111,97 @@ export default defineMsdmdCollection({ "file": "ptcna/neural/zeta.py", "id": "pcna_zeta" }, + { + "block": "BOUNDARIES", + "fields": { + "admin_only": "false", + "auth_boundary": "none", + "network_boundary": "none", + "owner": "Erin Spencer", + "pii": "none", + "secrets": "none", + "since": "unreleased", + "storage_boundary": "none", + "summary": "performs deterministic in-process inference and learning with no authentication, persistence, network, user-data, or administrative effect", + "user_data_boundary": "none" + }, + "file": "ptcna/runtime.py", + "id": "ptcna_runtime_local_boundary" + }, + { + "block": "CONTRACTS", + "fields": { + "class": "safety", + "given": "the target raises during inference", + "then": "PTCNARuntime raises by default and uses the fallback only when explicitly enabled while recording the target failure and actual backend" + }, + "file": "ptcna/runtime.py", + "id": "ptcna_failover_is_explicit_and_attributed" + }, + { + "block": "CONTRACTS", + "fields": { + "class": "correctness", + "given": "identical text and fresh HashedLinearFallback instances", + "then": "both produce the same bounded prediction under a fallback identity that is never labeled PTCNA" + }, + "file": "ptcna/runtime.py", + "id": "ptcna_fallback_is_distinct_and_deterministic" + }, + { + "block": "CONTRACTS", + "fields": { + "class": "correctness", + "given": "the fallback infers text and receives a positive bounded reward for the selected winner", + "then": "a second inference of the same text gives that winner a strictly greater linear score" + }, + "file": "ptcna/runtime.py", + "id": "ptcna_fallback_reward_changes_selected_score" + }, + { + "block": "CONTRACTS", + "fields": { + "class": "safety", + "given": "a reward is applied to an inference receipt", + "then": "only the backend named by backend_used receives the reward" + }, + "file": "ptcna/runtime.py", + "id": "ptcna_reward_follows_backend_receipt" + }, + { + "block": "CONTRACTS", + "fields": { + "class": "correctness", + "given": "non-empty text is inferred through PTCNAEngine", + "then": "the receipt identifies the experimental PTCNA backend and reports neural, circle, seed, and core layer state without transferring gradients to structural layers" + }, + "file": "ptcna/runtime.py", + "id": "ptcna_target_reports_four_live_layers" + }, + { + "block": "MODULE_BUILD", + "fields": { + "admin_only": "false", + "auth_boundary": "none", + "internal_surface": "_validate_text, _validate_reward, _attach_route", + "module_kind": "engine", + "module_name": "runtime", + "network_boundary": "none", + "owner": "Erin Spencer", + "public_surface": "PTCNAEngine, HashedLinearFallback, PTCNARuntime, InferenceBackend, PTCNA_BACKEND, FALLBACK_BACKEND", + "requires": "pcna_pcna, ptcna_prime_core_composition", + "rollback": "remove runtime exports while preserving the existing layer modules and PCNAEngine", + "rollout": "explicit public API; target selected by default and fallback selected or enabled by the caller", + "since": "unreleased", + "storage_boundary": "none", + "summary": "exposes the intended four-layer PTCNA path and a distinct dependable fallback behind one attributed task interface", + "tests": "ptcna/tests/test_runtime.py", + "unresolved": "representative task workload and whether either backend is useful under it", + "user_data_boundary": "none" + }, + "file": "ptcna/runtime.py", + "id": "ptcna_runtime_boundary" + }, { "block": "CONTRACTS", "fields": { @@ -1156,6 +1345,123 @@ export default defineMsdmdCollection({ "file": "ptcna/tests/test_contract_audit.py", "id": "check_contract_audit_complete_graph" }, + { + "block": "CHECKS", + "fields": { + "call": "self::test_backend_failure_stops_with_preselected_status", + "cleanup": "none", + "mutates": "none", + "proves": "ptcna_evaluation_propagates_backend_failure", + "requires": "python3", + "timeout": "30" + }, + "file": "ptcna/tests/test_evaluation.py", + "id": "check_ptcna_failure_propagation" + }, + { + "block": "CHECKS", + "fields": { + "call": "self::test_frozen_thresholds_produce_survival_and_falsification", + "cleanup": "none", + "mutates": "none", + "proves": "ptcna_evaluation_verdict_uses_frozen_thresholds", + "requires": "python3", + "timeout": "30" + }, + "file": "ptcna/tests/test_evaluation.py", + "id": "check_ptcna_frozen_verdicts" + }, + { + "block": "CHECKS", + "fields": { + "call": "self::test_plan_digest_is_stable_and_criteria_sensitive", + "cleanup": "none", + "mutates": "none", + "proves": "ptcna_evaluation_plan_freezes_verdict_inputs", + "requires": "python3", + "timeout": "30" + }, + "file": "ptcna/tests/test_evaluation.py", + "id": "check_ptcna_plan_digest" + }, + { + "block": "CHECKS", + "fields": { + "call": "self::test_target_failure_requires_explicit_attributed_failover", + "cleanup": "none", + "mutates": "none", + "proves": "ptcna_failover_is_explicit_and_attributed", + "requires": "python3, numpy", + "timeout": "30" + }, + "file": "ptcna/tests/test_runtime.py", + "id": "check_ptcna_explicit_failover" + }, + { + "block": "CHECKS", + "fields": { + "call": "self::test_fallback_is_deterministic_bounded_and_distinct", + "cleanup": "none", + "mutates": "none", + "proves": "ptcna_fallback_is_distinct_and_deterministic", + "requires": "python3, numpy", + "timeout": "30" + }, + "file": "ptcna/tests/test_runtime.py", + "id": "check_ptcna_fallback_determinism" + }, + { + "block": "CHECKS", + "fields": { + "call": "self::test_fallback_positive_reward_increases_selected_score", + "cleanup": "none", + "mutates": "none", + "proves": "ptcna_fallback_reward_changes_selected_score", + "requires": "python3, numpy", + "timeout": "30" + }, + "file": "ptcna/tests/test_runtime.py", + "id": "check_ptcna_fallback_reward" + }, + { + "block": "CHECKS", + "fields": { + "call": "self::test_reward_follows_the_recorded_backend", + "cleanup": "none", + "mutates": "none", + "proves": "ptcna_reward_follows_backend_receipt", + "requires": "python3, numpy", + "timeout": "30" + }, + "file": "ptcna/tests/test_runtime.py", + "id": "check_ptcna_reward_route" + }, + { + "block": "CHECKS", + "fields": { + "call": "self::test_root_exports_runtime_and_evaluation_surface", + "cleanup": "none", + "mutates": "none", + "proves": "ptcna_root_exports_runtime_boundary", + "requires": "python3", + "timeout": "30" + }, + "file": "ptcna/tests/test_runtime.py", + "id": "check_ptcna_root_runtime_exports" + }, + { + "block": "CHECKS", + "fields": { + "call": "self::test_target_reports_all_four_live_layers", + "cleanup": "none", + "mutates": "none", + "proves": "ptcna_target_reports_four_live_layers", + "requires": "python3, numpy", + "timeout": "30" + }, + "file": "ptcna/tests/test_runtime.py", + "id": "check_ptcna_target_four_layers" + }, { "block": "CHECKS", "fields": { @@ -1355,6 +1661,27 @@ export default defineMsdmdCollection({ "source_id": "prime_core_composition_runtime_boundary", "to": "Erin Spencer" }, + { + "from": "ptcna_evaluation_local_boundary", + "kind": "owns", + "source_block": "BOUNDARIES", + "source_id": "ptcna_evaluation_local_boundary", + "to": "Erin Spencer" + }, + { + "from": "ptcna_package_import_boundary", + "kind": "owns", + "source_block": "BOUNDARIES", + "source_id": "ptcna_package_import_boundary", + "to": "Erin Spencer" + }, + { + "from": "ptcna_runtime_local_boundary", + "kind": "owns", + "source_block": "BOUNDARIES", + "source_id": "ptcna_runtime_local_boundary", + "to": "Erin Spencer" + }, { "from": "ptcna_ucns_integration_runtime_boundary", "kind": "owns", @@ -1796,6 +2123,230 @@ export default defineMsdmdCollection({ "source_id": "check_prime_core_suspended_ucns", "to": "python3" }, + { + "from": "check_ptcna_explicit_failover", + "kind": "calls", + "source_block": "CHECKS", + "source_id": "check_ptcna_explicit_failover", + "to": "self::test_target_failure_requires_explicit_attributed_failover" + }, + { + "from": "check_ptcna_explicit_failover", + "kind": "claims_proves", + "source_block": "CHECKS", + "source_id": "check_ptcna_explicit_failover", + "to": "ptcna_failover_is_explicit_and_attributed" + }, + { + "from": "check_ptcna_explicit_failover", + "kind": "requires", + "source_block": "CHECKS", + "source_id": "check_ptcna_explicit_failover", + "to": "numpy" + }, + { + "from": "check_ptcna_explicit_failover", + "kind": "requires", + "source_block": "CHECKS", + "source_id": "check_ptcna_explicit_failover", + "to": "python3" + }, + { + "from": "check_ptcna_failure_propagation", + "kind": "calls", + "source_block": "CHECKS", + "source_id": "check_ptcna_failure_propagation", + "to": "self::test_backend_failure_stops_with_preselected_status" + }, + { + "from": "check_ptcna_failure_propagation", + "kind": "claims_proves", + "source_block": "CHECKS", + "source_id": "check_ptcna_failure_propagation", + "to": "ptcna_evaluation_propagates_backend_failure" + }, + { + "from": "check_ptcna_failure_propagation", + "kind": "requires", + "source_block": "CHECKS", + "source_id": "check_ptcna_failure_propagation", + "to": "python3" + }, + { + "from": "check_ptcna_fallback_determinism", + "kind": "calls", + "source_block": "CHECKS", + "source_id": "check_ptcna_fallback_determinism", + "to": "self::test_fallback_is_deterministic_bounded_and_distinct" + }, + { + "from": "check_ptcna_fallback_determinism", + "kind": "claims_proves", + "source_block": "CHECKS", + "source_id": "check_ptcna_fallback_determinism", + "to": "ptcna_fallback_is_distinct_and_deterministic" + }, + { + "from": "check_ptcna_fallback_determinism", + "kind": "requires", + "source_block": "CHECKS", + "source_id": "check_ptcna_fallback_determinism", + "to": "numpy" + }, + { + "from": "check_ptcna_fallback_determinism", + "kind": "requires", + "source_block": "CHECKS", + "source_id": "check_ptcna_fallback_determinism", + "to": "python3" + }, + { + "from": "check_ptcna_fallback_reward", + "kind": "calls", + "source_block": "CHECKS", + "source_id": "check_ptcna_fallback_reward", + "to": "self::test_fallback_positive_reward_increases_selected_score" + }, + { + "from": "check_ptcna_fallback_reward", + "kind": "claims_proves", + "source_block": "CHECKS", + "source_id": "check_ptcna_fallback_reward", + "to": "ptcna_fallback_reward_changes_selected_score" + }, + { + "from": "check_ptcna_fallback_reward", + "kind": "requires", + "source_block": "CHECKS", + "source_id": "check_ptcna_fallback_reward", + "to": "numpy" + }, + { + "from": "check_ptcna_fallback_reward", + "kind": "requires", + "source_block": "CHECKS", + "source_id": "check_ptcna_fallback_reward", + "to": "python3" + }, + { + "from": "check_ptcna_frozen_verdicts", + "kind": "calls", + "source_block": "CHECKS", + "source_id": "check_ptcna_frozen_verdicts", + "to": "self::test_frozen_thresholds_produce_survival_and_falsification" + }, + { + "from": "check_ptcna_frozen_verdicts", + "kind": "claims_proves", + "source_block": "CHECKS", + "source_id": "check_ptcna_frozen_verdicts", + "to": "ptcna_evaluation_verdict_uses_frozen_thresholds" + }, + { + "from": "check_ptcna_frozen_verdicts", + "kind": "requires", + "source_block": "CHECKS", + "source_id": "check_ptcna_frozen_verdicts", + "to": "python3" + }, + { + "from": "check_ptcna_plan_digest", + "kind": "calls", + "source_block": "CHECKS", + "source_id": "check_ptcna_plan_digest", + "to": "self::test_plan_digest_is_stable_and_criteria_sensitive" + }, + { + "from": "check_ptcna_plan_digest", + "kind": "claims_proves", + "source_block": "CHECKS", + "source_id": "check_ptcna_plan_digest", + "to": "ptcna_evaluation_plan_freezes_verdict_inputs" + }, + { + "from": "check_ptcna_plan_digest", + "kind": "requires", + "source_block": "CHECKS", + "source_id": "check_ptcna_plan_digest", + "to": "python3" + }, + { + "from": "check_ptcna_reward_route", + "kind": "calls", + "source_block": "CHECKS", + "source_id": "check_ptcna_reward_route", + "to": "self::test_reward_follows_the_recorded_backend" + }, + { + "from": "check_ptcna_reward_route", + "kind": "claims_proves", + "source_block": "CHECKS", + "source_id": "check_ptcna_reward_route", + "to": "ptcna_reward_follows_backend_receipt" + }, + { + "from": "check_ptcna_reward_route", + "kind": "requires", + "source_block": "CHECKS", + "source_id": "check_ptcna_reward_route", + "to": "numpy" + }, + { + "from": "check_ptcna_reward_route", + "kind": "requires", + "source_block": "CHECKS", + "source_id": "check_ptcna_reward_route", + "to": "python3" + }, + { + "from": "check_ptcna_root_runtime_exports", + "kind": "calls", + "source_block": "CHECKS", + "source_id": "check_ptcna_root_runtime_exports", + "to": "self::test_root_exports_runtime_and_evaluation_surface" + }, + { + "from": "check_ptcna_root_runtime_exports", + "kind": "claims_proves", + "source_block": "CHECKS", + "source_id": "check_ptcna_root_runtime_exports", + "to": "ptcna_root_exports_runtime_boundary" + }, + { + "from": "check_ptcna_root_runtime_exports", + "kind": "requires", + "source_block": "CHECKS", + "source_id": "check_ptcna_root_runtime_exports", + "to": "python3" + }, + { + "from": "check_ptcna_target_four_layers", + "kind": "calls", + "source_block": "CHECKS", + "source_id": "check_ptcna_target_four_layers", + "to": "self::test_target_reports_all_four_live_layers" + }, + { + "from": "check_ptcna_target_four_layers", + "kind": "claims_proves", + "source_block": "CHECKS", + "source_id": "check_ptcna_target_four_layers", + "to": "ptcna_target_reports_four_live_layers" + }, + { + "from": "check_ptcna_target_four_layers", + "kind": "requires", + "source_block": "CHECKS", + "source_id": "check_ptcna_target_four_layers", + "to": "numpy" + }, + { + "from": "check_ptcna_target_four_layers", + "kind": "requires", + "source_block": "CHECKS", + "source_id": "check_ptcna_target_four_layers", + "to": "python3" + }, { "from": "check_ptcna_ucns_fails_closed", "kind": "calls", @@ -1999,27 +2550,6 @@ export default defineMsdmdCollection({ "source_id": "check_zeta_suspends_without_provider", "to": "python3" }, - { - "from": "pcna_core_main", - "kind": "owns", - "source_block": "MODULE_BUILD", - "source_id": "pcna_core_main", - "to": "Erin Spencer" - }, - { - "from": "pcna_core_main", - "kind": "requires", - "source_block": "MODULE_BUILD", - "source_id": "pcna_core_main", - "to": "pcna_tensor_engine" - }, - { - "from": "pcna_core_main", - "kind": "requires", - "source_block": "MODULE_BUILD", - "source_id": "pcna_core_main", - "to": "pcna_topology" - }, { "from": "pcna_helix_vis", "kind": "owns", @@ -2286,6 +2816,20 @@ export default defineMsdmdCollection({ "source_id": "ptcna_fiq_host", "to": "none" }, + { + "from": "ptcna_frozen_evaluation", + "kind": "owns", + "source_block": "MODULE_BUILD", + "source_id": "ptcna_frozen_evaluation", + "to": "Erin Spencer" + }, + { + "from": "ptcna_frozen_evaluation", + "kind": "requires", + "source_block": "MODULE_BUILD", + "source_id": "ptcna_frozen_evaluation", + "to": "ptcna_runtime_boundary" + }, { "from": "ptcna_neural_scalar", "kind": "owns", @@ -2300,6 +2844,34 @@ export default defineMsdmdCollection({ "source_id": "ptcna_neural_scalar", "to": "none" }, + { + "from": "ptcna_package_surface", + "kind": "owns", + "source_block": "MODULE_BUILD", + "source_id": "ptcna_package_surface", + "to": "Erin Spencer" + }, + { + "from": "ptcna_package_surface", + "kind": "requires", + "source_block": "MODULE_BUILD", + "source_id": "ptcna_package_surface", + "to": "ptcna_frozen_evaluation" + }, + { + "from": "ptcna_package_surface", + "kind": "requires", + "source_block": "MODULE_BUILD", + "source_id": "ptcna_package_surface", + "to": "ptcna_runtime_boundary" + }, + { + "from": "ptcna_package_surface", + "kind": "requires", + "source_block": "MODULE_BUILD", + "source_id": "ptcna_package_surface", + "to": "ptcna_ucns_integration" + }, { "from": "ptcna_prime_core_composition", "kind": "owns", @@ -2335,6 +2907,27 @@ export default defineMsdmdCollection({ "source_id": "ptcna_prime_core_composition", "to": "ptcna_ucns_integration" }, + { + "from": "ptcna_runtime_boundary", + "kind": "owns", + "source_block": "MODULE_BUILD", + "source_id": "ptcna_runtime_boundary", + "to": "Erin Spencer" + }, + { + "from": "ptcna_runtime_boundary", + "kind": "requires", + "source_block": "MODULE_BUILD", + "source_id": "ptcna_runtime_boundary", + "to": "pcna_pcna" + }, + { + "from": "ptcna_runtime_boundary", + "kind": "requires", + "source_block": "MODULE_BUILD", + "source_id": "ptcna_runtime_boundary", + "to": "ptcna_prime_core_composition" + }, { "from": "ptcna_ucns_integration", "kind": "owns",