pycforge 0.15.2__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.
- pycforge/__init__.py +8 -0
- pycforge/__main__.py +2 -0
- pycforge/_version.py +1 -0
- pycforge/converter/__init__.py +0 -0
- pycforge/converter/analysis/__init__.py +5 -0
- pycforge/converter/analysis/functions.py +723 -0
- pycforge/converter/analysis/model.py +158 -0
- pycforge/converter/analysis/planning.py +464 -0
- pycforge/converter/analysis/stage.py +1976 -0
- pycforge/converter/analysis/symbols.py +237 -0
- pycforge/converter/analysis/validation.py +2166 -0
- pycforge/converter/c_output/__init__.py +2 -0
- pycforge/converter/c_output/conformance.py +297 -0
- pycforge/converter/c_output/renderer.py +220 -0
- pycforge/converter/conditional_regions/__init__.py +71 -0
- pycforge/converter/conditional_regions/analysis.py +481 -0
- pycforge/converter/conditional_regions/lowering.py +579 -0
- pycforge/converter/conditional_regions/model.py +243 -0
- pycforge/converter/conditional_regions/validation.py +690 -0
- pycforge/converter/containers/__init__.py +19 -0
- pycforge/converter/containers/analysis.py +542 -0
- pycforge/converter/containers/lowering.py +290 -0
- pycforge/converter/containers/model.py +146 -0
- pycforge/converter/contracts/__init__.py +0 -0
- pycforge/converter/contracts/configuration.py +178 -0
- pycforge/converter/contracts/identifiers.py +68 -0
- pycforge/converter/contracts/versions.py +71 -0
- pycforge/converter/core/__init__.py +0 -0
- pycforge/converter/core/artifact_io.py +87 -0
- pycforge/converter/core/cancellation.py +7 -0
- pycforge/converter/core/canonicalization.py +254 -0
- pycforge/converter/core/context.py +13 -0
- pycforge/converter/core/diagnostics.py +95 -0
- pycforge/converter/core/enums.py +23 -0
- pycforge/converter/core/fingerprint.py +22 -0
- pycforge/converter/core/pipeline.py +8 -0
- pycforge/converter/core/progress.py +25 -0
- pycforge/converter/core/request.py +50 -0
- pycforge/converter/core/resource_policy.py +31 -0
- pycforge/converter/core/result.py +23 -0
- pycforge/converter/core/serialization.py +36 -0
- pycforge/converter/core/stage.py +10 -0
- pycforge/converter/core/stage_artifact.py +80 -0
- pycforge/converter/core/stage_outcome.py +15 -0
- pycforge/converter/decision_trace/__init__.py +0 -0
- pycforge/converter/decision_trace/recorder.py +52 -0
- pycforge/converter/facade.py +459 -0
- pycforge/converter/frontend/__init__.py +4 -0
- pycforge/converter/frontend/normalizer.py +59 -0
- pycforge/converter/frontend/parser.py +20 -0
- pycforge/converter/frontend/source_document.py +93 -0
- pycforge/converter/frontend/stages.py +518 -0
- pycforge/converter/frontend/validation.py +76 -0
- pycforge/converter/io/__init__.py +0 -0
- pycforge/converter/io/atomic_writer.py +33 -0
- pycforge/converter/ir/__init__.py +1 -0
- pycforge/converter/ir/c_ir/__init__.py +4 -0
- pycforge/converter/ir/c_ir/builder.py +26 -0
- pycforge/converter/ir/c_ir/model.py +318 -0
- pycforge/converter/ir/c_ir/serialization.py +88 -0
- pycforge/converter/ir/c_ir/validation.py +834 -0
- pycforge/converter/ir/python_ir/__init__.py +17 -0
- pycforge/converter/ir/python_ir/nodes.py +86 -0
- pycforge/converter/keyword_calls/__init__.py +68 -0
- pycforge/converter/keyword_calls/analysis.py +458 -0
- pycforge/converter/keyword_calls/lowering.py +271 -0
- pycforge/converter/keyword_calls/model.py +304 -0
- pycforge/converter/keyword_calls/validation.py +802 -0
- pycforge/converter/keyword_only_calls/__init__.py +68 -0
- pycforge/converter/keyword_only_calls/analysis.py +640 -0
- pycforge/converter/keyword_only_calls/lowering.py +376 -0
- pycforge/converter/keyword_only_calls/model.py +328 -0
- pycforge/converter/keyword_only_calls/validation.py +1357 -0
- pycforge/converter/lowering.py +1000 -0
- pycforge/converter/modules/__init__.py +13 -0
- pycforge/converter/modules/analysis.py +1250 -0
- pycforge/converter/modules/lowering.py +200 -0
- pycforge/converter/modules/model.py +73 -0
- pycforge/converter/modules/stage.py +192 -0
- pycforge/converter/numeric_semantics/__init__.py +23 -0
- pycforge/converter/numeric_semantics/analysis.py +420 -0
- pycforge/converter/numeric_semantics/lowering.py +153 -0
- pycforge/converter/numeric_semantics/model.py +123 -0
- pycforge/converter/records/__init__.py +34 -0
- pycforge/converter/records/analysis.py +1394 -0
- pycforge/converter/records/lowering.py +393 -0
- pycforge/converter/records/model.py +319 -0
- pycforge/converter/rules/__init__.py +3 -0
- pycforge/converter/support_templates/__init__.py +49 -0
- pycforge/converter/support_templates/assembly.py +106 -0
- pycforge/converter/support_templates/factories.py +348 -0
- pycforge/converter/support_templates/model.py +159 -0
- pycforge/converter/support_templates/registry.py +388 -0
- pycforge/converter/telemetry/__init__.py +0 -0
- pycforge/converter/telemetry/sink.py +39 -0
- pycforge/ide/__init__.py +19 -0
- pycforge/ide/__main__.py +5 -0
- pycforge/ide/_worker_event_codec.py +276 -0
- pycforge/ide/_worker_protocol_json.py +197 -0
- pycforge/ide/_worker_protocol_types.py +90 -0
- pycforge/ide/_worker_request_codec.py +200 -0
- pycforge/ide/_worker_request_data.py +260 -0
- pycforge/ide/_worker_result_data.py +343 -0
- pycforge/ide/action_contract.py +469 -0
- pycforge/ide/action_validation.py +229 -0
- pycforge/ide/command_palette.py +223 -0
- pycforge/ide/controller.py +904 -0
- pycforge/ide/controller_conversion.py +546 -0
- pycforge/ide/controller_io.py +205 -0
- pycforge/ide/editor.py +951 -0
- pycforge/ide/editor_commands_qt.py +274 -0
- pycforge/ide/editor_lexical.py +43 -0
- pycforge/ide/editor_sidebars.py +236 -0
- pycforge/ide/editor_syntax.py +243 -0
- pycforge/ide/find_replace.py +535 -0
- pycforge/ide/icons.py +91 -0
- pycforge/ide/io_service.py +196 -0
- pycforge/ide/model.py +164 -0
- pycforge/ide/panels.py +903 -0
- pycforge/ide/positions.py +220 -0
- pycforge/ide/process_worker.py +130 -0
- pycforge/ide/qt.py +230 -0
- pycforge/ide/qt_actions.py +418 -0
- pycforge/ide/qt_close.py +169 -0
- pycforge/ide/qt_command_palette.py +297 -0
- pycforge/ide/qt_contract.py +220 -0
- pycforge/ide/qt_documents.py +590 -0
- pycforge/ide/qt_editor_buffers.py +113 -0
- pycforge/ide/qt_editor_surfaces.py +112 -0
- pycforge/ide/qt_menus.py +324 -0
- pycforge/ide/qt_projection.py +500 -0
- pycforge/ide/qt_shell.py +348 -0
- pycforge/ide/qt_shell_interactions.py +320 -0
- pycforge/ide/qt_state.py +393 -0
- pycforge/ide/qt_workspace_features.py +398 -0
- pycforge/ide/qt_workspace_navigation.py +208 -0
- pycforge/ide/qt_workspace_observers.py +173 -0
- pycforge/ide/qt_workspace_panels.py +545 -0
- pycforge/ide/qt_workspace_widgets.py +228 -0
- pycforge/ide/resources/icons/about.svg +1 -0
- pycforge/ide/resources/icons/add-document.svg +1 -0
- pycforge/ide/resources/icons/brand-mark.svg +1 -0
- pycforge/ide/resources/icons/bundle-search.svg +1 -0
- pycforge/ide/resources/icons/cancel.svg +1 -0
- pycforge/ide/resources/icons/check.svg +1 -0
- pycforge/ide/resources/icons/chevron-right.svg +1 -0
- pycforge/ide/resources/icons/close.svg +1 -0
- pycforge/ide/resources/icons/collapse-all.svg +1 -0
- pycforge/ide/resources/icons/command-palette.svg +1 -0
- pycforge/ide/resources/icons/convert.svg +1 -0
- pycforge/ide/resources/icons/copy.svg +1 -0
- pycforge/ide/resources/icons/cut.svg +1 -0
- pycforge/ide/resources/icons/decision-trace.svg +1 -0
- pycforge/ide/resources/icons/details.svg +1 -0
- pycforge/ide/resources/icons/diagnostics.svg +1 -0
- pycforge/ide/resources/icons/duplicate-line.svg +1 -0
- pycforge/ide/resources/icons/exit.svg +1 -0
- pycforge/ide/resources/icons/expand-all.svg +1 -0
- pycforge/ide/resources/icons/export.svg +1 -0
- pycforge/ide/resources/icons/find.svg +1 -0
- pycforge/ide/resources/icons/go-to-line.svg +1 -0
- pycforge/ide/resources/icons/go-to-output.svg +1 -0
- pycforge/ide/resources/icons/go-to-source.svg +1 -0
- pycforge/ide/resources/icons/history.svg +1 -0
- pycforge/ide/resources/icons/indent.svg +1 -0
- pycforge/ide/resources/icons/link-c.svg +1 -0
- pycforge/ide/resources/icons/mappings.svg +1 -0
- pycforge/ide/resources/icons/module.svg +1 -0
- pycforge/ide/resources/icons/move-down.svg +1 -0
- pycforge/ide/resources/icons/move-line-down.svg +1 -0
- pycforge/ide/resources/icons/move-line-up.svg +1 -0
- pycforge/ide/resources/icons/move-up.svg +1 -0
- pycforge/ide/resources/icons/next.svg +1 -0
- pycforge/ide/resources/icons/open.svg +1 -0
- pycforge/ide/resources/icons/outdent.svg +1 -0
- pycforge/ide/resources/icons/outline.svg +1 -0
- pycforge/ide/resources/icons/paste.svg +1 -0
- pycforge/ide/resources/icons/previous.svg +1 -0
- pycforge/ide/resources/icons/primary-module.svg +1 -0
- pycforge/ide/resources/icons/redo.svg +1 -0
- pycforge/ide/resources/icons/remove-document.svg +1 -0
- pycforge/ide/resources/icons/replace.svg +1 -0
- pycforge/ide/resources/icons/save-as.svg +1 -0
- pycforge/ide/resources/icons/save.svg +1 -0
- pycforge/ide/resources/icons/select-all.svg +1 -0
- pycforge/ide/resources/icons/settings.svg +1 -0
- pycforge/ide/resources/icons/show-c.svg +1 -0
- pycforge/ide/resources/icons/split-view.svg +1 -0
- pycforge/ide/resources/icons/summary.svg +1 -0
- pycforge/ide/resources/icons/telemetry.svg +1 -0
- pycforge/ide/resources/icons/toggle-comment.svg +1 -0
- pycforge/ide/resources/icons/toggle-fold.svg +1 -0
- pycforge/ide/resources/icons/undo.svg +1 -0
- pycforge/ide/resources/icons/whitespace.svg +1 -0
- pycforge/ide/revisions.py +400 -0
- pycforge/ide/search_service.py +280 -0
- pycforge/ide/session_history.py +150 -0
- pycforge/ide/source_editing.py +417 -0
- pycforge/ide/source_structure.py +558 -0
- pycforge/ide/source_structure_async.py +191 -0
- pycforge/ide/supervisor.py +503 -0
- pycforge/ide/theme.py +119 -0
- pycforge/ide/theme_stylesheet.py +598 -0
- pycforge/ide/theme_workspace_stylesheet.py +155 -0
- pycforge/ide/visual_tokens.py +142 -0
- pycforge/ide/worker_protocol.py +80 -0
- pycforge/ide/workspace_search.py +462 -0
- pycforge/ide/workspace_session.py +256 -0
- pycforge/laboratory/__init__.py +6 -0
- pycforge/laboratory/audits.py +2244 -0
- pycforge/laboratory/checkpoint_e.py +2685 -0
- pycforge/laboratory/cli.py +119 -0
- pycforge/laboratory/exit_codes.py +11 -0
- pycforge/laboratory/keyword_audit.py +661 -0
- pycforge/laboratory/keyword_only_audit.py +481 -0
- pycforge-0.15.2.dist-info/METADATA +209 -0
- pycforge-0.15.2.dist-info/RECORD +221 -0
- pycforge-0.15.2.dist-info/WHEEL +5 -0
- pycforge-0.15.2.dist-info/entry_points.txt +5 -0
- pycforge-0.15.2.dist-info/licenses/LICENSE +674 -0
- pycforge-0.15.2.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,661 @@
|
|
|
1
|
+
"""Authenticated laboratory audit for the bounded Phase 14C keyword slice."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import hashlib
|
|
6
|
+
import json
|
|
7
|
+
import subprocess
|
|
8
|
+
import sys
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
from typing import Any
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def _kind_dicts(value: Any, kind: str) -> list[dict[str, Any]]:
|
|
14
|
+
found: list[dict[str, Any]] = []
|
|
15
|
+
if isinstance(value, dict):
|
|
16
|
+
if value.get("kind") == kind:
|
|
17
|
+
found.append(value)
|
|
18
|
+
for child in value.values():
|
|
19
|
+
found.extend(_kind_dicts(child, kind))
|
|
20
|
+
elif isinstance(value, (list, tuple)):
|
|
21
|
+
for child in value:
|
|
22
|
+
found.extend(_kind_dicts(child, kind))
|
|
23
|
+
return found
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def _table(payload: dict[str, Any], table_id: str) -> dict[str, Any]:
|
|
27
|
+
return next(
|
|
28
|
+
item
|
|
29
|
+
for item in payload.get("fact_tables", ())
|
|
30
|
+
if item.get("table_id") == table_id
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def _facts(payload: dict[str, Any], table_id: str) -> list[dict[str, Any]]:
|
|
35
|
+
return [
|
|
36
|
+
item.get("value", {})
|
|
37
|
+
for item in _table(payload, table_id).get("records", ())
|
|
38
|
+
]
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def _lowering_proof(
|
|
42
|
+
payload: dict[str, Any], fact_values: list[dict[str, Any]]
|
|
43
|
+
) -> tuple[bool, list[dict[str, Any]]]:
|
|
44
|
+
"""Reconstruct source staging and formal-reference order from C IR."""
|
|
45
|
+
|
|
46
|
+
c_ir = payload.get("c_ir", {})
|
|
47
|
+
declarations = _kind_dicts(c_ir, "CVariableDeclaration")
|
|
48
|
+
calls = _kind_dicts(c_ir, "CCallExpr")
|
|
49
|
+
evidence: list[dict[str, Any]] = []
|
|
50
|
+
valid = True
|
|
51
|
+
for fact in fact_values:
|
|
52
|
+
call_id = fact.get("call_node_id")
|
|
53
|
+
source_ids = list(fact.get("source_argument_node_ids", ()))
|
|
54
|
+
staged = [
|
|
55
|
+
item
|
|
56
|
+
for item in declarations
|
|
57
|
+
if str(item.get("node_id", "")).startswith("c-arg-temp-")
|
|
58
|
+
and call_id in item.get("provenance", {}).get("source_node_ids", ())
|
|
59
|
+
]
|
|
60
|
+
staged_source: list[str | None] = []
|
|
61
|
+
staged_bindings: list[str | None] = []
|
|
62
|
+
for declaration in staged:
|
|
63
|
+
matches = [
|
|
64
|
+
source_id
|
|
65
|
+
for source_id in source_ids
|
|
66
|
+
if source_id
|
|
67
|
+
in declaration.get("provenance", {}).get("source_node_ids", ())
|
|
68
|
+
]
|
|
69
|
+
staged_source.append(matches[0] if len(matches) == 1 else None)
|
|
70
|
+
staged_bindings.append(
|
|
71
|
+
declaration.get("identifier", {}).get("binding_id")
|
|
72
|
+
)
|
|
73
|
+
target_calls = [
|
|
74
|
+
item
|
|
75
|
+
for item in calls
|
|
76
|
+
if call_id in item.get("provenance", {}).get("source_node_ids", ())
|
|
77
|
+
]
|
|
78
|
+
target_call = target_calls[0] if len(target_calls) == 1 else {}
|
|
79
|
+
actual_formal = [
|
|
80
|
+
item.get("binding_id") for item in target_call.get("arguments", ())
|
|
81
|
+
]
|
|
82
|
+
permutation = list(fact.get("parameter_to_source_ordinals", ()))
|
|
83
|
+
permutation_valid = (
|
|
84
|
+
len(permutation) == len(staged_bindings)
|
|
85
|
+
and all(
|
|
86
|
+
isinstance(index, int) and 0 <= index < len(staged_bindings)
|
|
87
|
+
for index in permutation
|
|
88
|
+
)
|
|
89
|
+
)
|
|
90
|
+
expected_formal = (
|
|
91
|
+
[staged_bindings[index] for index in permutation]
|
|
92
|
+
if permutation_valid
|
|
93
|
+
else []
|
|
94
|
+
)
|
|
95
|
+
item_valid = (
|
|
96
|
+
staged_source == source_ids
|
|
97
|
+
and len(staged_bindings) == len(source_ids)
|
|
98
|
+
and len(set(staged_bindings)) == len(staged_bindings)
|
|
99
|
+
and len(target_calls) == 1
|
|
100
|
+
and actual_formal == expected_formal
|
|
101
|
+
and all(
|
|
102
|
+
argument.get("kind") == "CIdentifierRef"
|
|
103
|
+
for argument in target_call.get("arguments", ())
|
|
104
|
+
)
|
|
105
|
+
)
|
|
106
|
+
valid = valid and item_valid
|
|
107
|
+
evidence.append(
|
|
108
|
+
{
|
|
109
|
+
"call_node_id": call_id,
|
|
110
|
+
"source_order": staged_source,
|
|
111
|
+
"parameter_to_source_ordinals": permutation,
|
|
112
|
+
"formal_reference_binding_ids": actual_formal,
|
|
113
|
+
"valid": item_valid,
|
|
114
|
+
}
|
|
115
|
+
)
|
|
116
|
+
return valid, evidence
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
def audit_keyword(root: Path) -> dict[str, Any]:
|
|
120
|
+
"""Independently gate direct keyword binding without invoking C tools."""
|
|
121
|
+
|
|
122
|
+
from pycforge import (
|
|
123
|
+
ConversionRequest,
|
|
124
|
+
PythonToCConverter,
|
|
125
|
+
ResultStatus,
|
|
126
|
+
SourceBundle,
|
|
127
|
+
SourceDocumentInput,
|
|
128
|
+
)
|
|
129
|
+
from pycforge.converter.c_output import validate_c_text
|
|
130
|
+
from pycforge.converter.contracts.configuration import (
|
|
131
|
+
PHASE14B_RENDERER,
|
|
132
|
+
PHASE14B_RULE_SET,
|
|
133
|
+
PHASE14C_RENDERER,
|
|
134
|
+
PHASE14C_RULE_SET,
|
|
135
|
+
)
|
|
136
|
+
from pycforge.converter.contracts.versions import (
|
|
137
|
+
KEYWORD_CALL_FACT_SCHEMA,
|
|
138
|
+
PHASE14C_C_IR_SCHEMA,
|
|
139
|
+
PHASE14C_CONVERSION_PLAN_SCHEMA,
|
|
140
|
+
PHASE14C_CONVERSION_SUMMARY_SCHEMA,
|
|
141
|
+
PHASE14C_DECISION_TRACE_SCHEMA,
|
|
142
|
+
PHASE14C_GENERATED_C_SCHEMA,
|
|
143
|
+
RESULT_SCHEMA_VERSION,
|
|
144
|
+
)
|
|
145
|
+
from pycforge.converter.core.request import ObservationOptions
|
|
146
|
+
from pycforge.converter.core.serialization import result_to_json
|
|
147
|
+
from pycforge.converter.keyword_calls import (
|
|
148
|
+
KEYWORD_CALL_KEY_DOMAIN,
|
|
149
|
+
KEYWORD_CALL_LOWERING_SHAPE,
|
|
150
|
+
KEYWORD_CALL_OBLIGATIONS,
|
|
151
|
+
KEYWORD_CALL_PROVENANCE_EVIDENCE,
|
|
152
|
+
KEYWORD_CALL_RULE_ID,
|
|
153
|
+
KEYWORD_CALL_RULE_VERSION,
|
|
154
|
+
KEYWORD_CALL_TABLE_DEPENDENCIES,
|
|
155
|
+
KEYWORD_CALL_TABLE_ID,
|
|
156
|
+
validate_keyword_call_binding_facts,
|
|
157
|
+
)
|
|
158
|
+
from pycforge.converter.support_templates import default_helper_registry
|
|
159
|
+
|
|
160
|
+
expected_obligations = (
|
|
161
|
+
"direct-source-target-resolved-once",
|
|
162
|
+
"explicit-keywords-only-no-unpacking",
|
|
163
|
+
"positional-prefix-bound-in-order",
|
|
164
|
+
"keyword-names-bound-to-positional-or-keyword-parameters",
|
|
165
|
+
"parameter-coverage-exact",
|
|
166
|
+
"argument-representations-compatible-after-binding",
|
|
167
|
+
"source-arguments-evaluated-left-to-right-once",
|
|
168
|
+
"argument-temporaries-reordered-only-after-evaluation",
|
|
169
|
+
"c-call-arguments-in-formal-order",
|
|
170
|
+
"parameter-ownership-boundary-explicit",
|
|
171
|
+
"runtime-binding-failure-absent",
|
|
172
|
+
"allocation-and-cleanup-absent",
|
|
173
|
+
"structured-c-ir-only",
|
|
174
|
+
"source-provenance-anchored",
|
|
175
|
+
"cancellation-safe-points-honored",
|
|
176
|
+
"target-contract-exact",
|
|
177
|
+
)
|
|
178
|
+
expected_dependencies = (
|
|
179
|
+
"binding-facts",
|
|
180
|
+
"function-signature-facts",
|
|
181
|
+
"value-category-facts",
|
|
182
|
+
"call-target-facts",
|
|
183
|
+
"evaluation-order-facts",
|
|
184
|
+
)
|
|
185
|
+
expected_provenance = (
|
|
186
|
+
"direct-source-target",
|
|
187
|
+
"exact-explicit-keyword-names",
|
|
188
|
+
"complete-parameter-coverage",
|
|
189
|
+
"source-order-evaluation",
|
|
190
|
+
"formal-order-reference-permutation",
|
|
191
|
+
"single-evaluation",
|
|
192
|
+
)
|
|
193
|
+
source = (
|
|
194
|
+
"def mark_int(value: int) -> int:\n return value\n\n"
|
|
195
|
+
"def mark_bool(value: bool) -> bool:\n return value\n\n"
|
|
196
|
+
"def mark_float(value: float) -> float:\n return value\n\n"
|
|
197
|
+
"def choose(left: int, flag: bool, ratio: float) -> int:\n"
|
|
198
|
+
" return left\n\n"
|
|
199
|
+
"def direct(x: int, y: bool, z: float) -> int:\n"
|
|
200
|
+
" return choose(left=x, flag=y, ratio=z)\n\n"
|
|
201
|
+
"def reordered(x: int, y: bool, z: float) -> int:\n"
|
|
202
|
+
" return choose(ratio=mark_float(z), left=mark_int(x), flag=mark_bool(y))\n"
|
|
203
|
+
)
|
|
204
|
+
cross_primary = (
|
|
205
|
+
"from lib import choose\n\n"
|
|
206
|
+
"def run(value: int, flag: bool, ratio: float) -> int:\n"
|
|
207
|
+
" return choose(ratio=ratio, flag=flag, left=value)\n"
|
|
208
|
+
)
|
|
209
|
+
cross_companion = (
|
|
210
|
+
"def choose(left: int, flag: bool, ratio: float) -> int:\n"
|
|
211
|
+
" return left\n"
|
|
212
|
+
)
|
|
213
|
+
sink = "def sink(value: int, flag: bool) -> int:\n return value\n\n"
|
|
214
|
+
record = (
|
|
215
|
+
"class Sample:\n count: int\n"
|
|
216
|
+
" def __init__(self, count: int) -> None:\n"
|
|
217
|
+
" self.count = count\n\n"
|
|
218
|
+
"def run(value: int) -> int:\n"
|
|
219
|
+
" sample = Sample(count=value)\n return value\n"
|
|
220
|
+
)
|
|
221
|
+
rejections = {
|
|
222
|
+
"star-positional": ("PYC2910", "def sink(value: int) -> int:\n return value\n\ndef run(value: int) -> int:\n return sink(*value)\n"),
|
|
223
|
+
"star-keyword": ("PYC2910", "def sink(value: int) -> int:\n return value\n\ndef run(value: int) -> int:\n return sink(**value)\n"),
|
|
224
|
+
"positional-only-name": ("PYC2912", "def sink(value: int, /, flag: bool) -> int:\n return value\n\ndef run(value: int, flag: bool) -> int:\n return sink(value=value, flag=flag)\n"),
|
|
225
|
+
"unknown-name": ("PYC2912", sink + "def run(value: int, flag: bool) -> int:\n return sink(missing=value, flag=flag)\n"),
|
|
226
|
+
"positional-keyword-collision": ("PYC2912", sink + "def run(value: int, flag: bool) -> int:\n return sink(value, value=value, flag=flag)\n"),
|
|
227
|
+
"duplicate-keyword": ("PYC2912", sink + "def run(value: int, flag: bool) -> int:\n return sink(value=value, flag=flag, value=value)\n"),
|
|
228
|
+
"missing-parameter": ("PYC2904", sink + "def run(value: int) -> int:\n return sink(value=value)\n"),
|
|
229
|
+
"excess-positional": ("PYC2904", sink + "def run(value: int, flag: bool) -> int:\n return sink(value, flag, value)\n"),
|
|
230
|
+
"mapped-category": ("PYC2905", sink + "def run(value: int, flag: bool) -> int:\n return sink(flag=value, value=flag)\n"),
|
|
231
|
+
"default-target": ("PYC2911", "def sink(value: int, flag: bool = True) -> int:\n return value\n\ndef run(value: int, flag: bool) -> int:\n return sink(flag=flag, value=value)\n"),
|
|
232
|
+
"keyword-only-target": ("PYC2911", "def sink(value: int, *, flag: bool) -> int:\n return value\n\ndef run(value: int, flag: bool) -> int:\n return sink(flag=flag, value=value)\n"),
|
|
233
|
+
"variadic-target": ("PYC2911", "def sink(value: int, *rest: int) -> int:\n return value\n\ndef run(value: int) -> int:\n return sink(value=value)\n"),
|
|
234
|
+
"range-keyword": ("PYC2842", "def run() -> int:\n total = 0\n for item in range(stop=3):\n total = total + item\n return total\n"),
|
|
235
|
+
"record-constructor-keyword": ("PYC3605", record),
|
|
236
|
+
"dynamic-target": ("PYC2901", "def run(value: int) -> int:\n return missing(value=value)\n"),
|
|
237
|
+
"recursive-target": ("PYC2920", "def run(value: int) -> int:\n return run(value=value)\n"),
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
try:
|
|
241
|
+
converter = PythonToCConverter()
|
|
242
|
+
observation = ObservationOptions("Full", False)
|
|
243
|
+
def phase14c_request(text: str) -> ConversionRequest:
|
|
244
|
+
return ConversionRequest.from_source(
|
|
245
|
+
text,
|
|
246
|
+
rule_set_version=PHASE14C_RULE_SET,
|
|
247
|
+
renderer_version=PHASE14C_RENDERER,
|
|
248
|
+
)
|
|
249
|
+
accepted = converter.convert(
|
|
250
|
+
phase14c_request(source), observation=observation
|
|
251
|
+
)
|
|
252
|
+
repeated = converter.convert(
|
|
253
|
+
phase14c_request(source), observation=observation
|
|
254
|
+
)
|
|
255
|
+
if accepted.stage_artifact is None:
|
|
256
|
+
raise ValueError("keyword conversion omitted its final artifact")
|
|
257
|
+
payload = accepted.stage_artifact.payload
|
|
258
|
+
summary = accepted.conversion_summary or {}
|
|
259
|
+
trace = accepted.decision_trace or {}
|
|
260
|
+
active_contracts = {
|
|
261
|
+
"rule_set": PHASE14C_RULE_SET,
|
|
262
|
+
"renderer": PHASE14C_RENDERER,
|
|
263
|
+
"keyword_call_facts": KEYWORD_CALL_FACT_SCHEMA,
|
|
264
|
+
"conversion_plan": PHASE14C_CONVERSION_PLAN_SCHEMA,
|
|
265
|
+
"c_ir": PHASE14C_C_IR_SCHEMA,
|
|
266
|
+
"generated_c": PHASE14C_GENERATED_C_SCHEMA,
|
|
267
|
+
"conversion_summary": PHASE14C_CONVERSION_SUMMARY_SCHEMA,
|
|
268
|
+
"decision_trace": PHASE14C_DECISION_TRACE_SCHEMA,
|
|
269
|
+
"result_serialization": RESULT_SCHEMA_VERSION,
|
|
270
|
+
}
|
|
271
|
+
active_contracts_valid = active_contracts == {
|
|
272
|
+
"rule_set": "phase14-direct-keyword-calls-v0.14.2",
|
|
273
|
+
"renderer": "c-renderer-v0.14.2",
|
|
274
|
+
"keyword_call_facts": "fact-table/0.14.2",
|
|
275
|
+
"conversion_plan": "conversion-plan/0.14.2",
|
|
276
|
+
"c_ir": "c-ir/0.14.2",
|
|
277
|
+
"generated_c": "generated-c/0.14.2",
|
|
278
|
+
"conversion_summary": "pycforge.conversion-summary/0.14.2",
|
|
279
|
+
"decision_trace": "pycforge.decision-trace/0.14.2",
|
|
280
|
+
"result_serialization": "0.5",
|
|
281
|
+
}
|
|
282
|
+
identity_valid = (
|
|
283
|
+
active_contracts_valid
|
|
284
|
+
and accepted.status is ResultStatus.CONVERTED
|
|
285
|
+
and accepted.generated_c is not None
|
|
286
|
+
and accepted.stage_artifact.kind == "generated_c"
|
|
287
|
+
and accepted.stage_artifact.schema_version == "0.14.2"
|
|
288
|
+
and payload.get("schema_version") == PHASE14C_GENERATED_C_SCHEMA
|
|
289
|
+
and payload.get("c_ir_schema") == PHASE14C_C_IR_SCHEMA
|
|
290
|
+
and payload.get("c_ir", {}).get("schema_version") == PHASE14C_C_IR_SCHEMA
|
|
291
|
+
and payload.get("rule_set_version") == PHASE14C_RULE_SET
|
|
292
|
+
and payload.get("renderer_version") == PHASE14C_RENDERER
|
|
293
|
+
and summary.get("schema_version") == PHASE14C_CONVERSION_SUMMARY_SCHEMA
|
|
294
|
+
and trace.get("schema_version") == PHASE14C_DECISION_TRACE_SCHEMA
|
|
295
|
+
)
|
|
296
|
+
constants_valid = (
|
|
297
|
+
KEYWORD_CALL_TABLE_ID == "keyword-call-binding-facts"
|
|
298
|
+
and KEYWORD_CALL_KEY_DOMAIN == "keyword-call-node-id"
|
|
299
|
+
and KEYWORD_CALL_LOWERING_SHAPE
|
|
300
|
+
== "source-order-temporaries-formal-order-references-v1"
|
|
301
|
+
and KEYWORD_CALL_RULE_ID == "phase14.keyword_call.exact_binding"
|
|
302
|
+
and KEYWORD_CALL_RULE_VERSION == "0.14.2"
|
|
303
|
+
and KEYWORD_CALL_OBLIGATIONS == expected_obligations
|
|
304
|
+
and KEYWORD_CALL_TABLE_DEPENDENCIES == expected_dependencies
|
|
305
|
+
and KEYWORD_CALL_PROVENANCE_EVIDENCE == expected_provenance
|
|
306
|
+
)
|
|
307
|
+
fact_table = _table(payload, KEYWORD_CALL_TABLE_ID)
|
|
308
|
+
records = list(fact_table.get("records", ()))
|
|
309
|
+
fact_values = _facts(payload, KEYWORD_CALL_TABLE_ID)
|
|
310
|
+
table_valid = (
|
|
311
|
+
fact_table.get("schema_version") == KEYWORD_CALL_FACT_SCHEMA
|
|
312
|
+
and fact_table.get("producer_stage") == "analysis.plan"
|
|
313
|
+
and fact_table.get("key_domain") == KEYWORD_CALL_KEY_DOMAIN
|
|
314
|
+
and fact_table.get("completeness") == "complete"
|
|
315
|
+
and tuple(fact_table.get("invalidation_dependencies", ()))
|
|
316
|
+
== expected_dependencies
|
|
317
|
+
and len(records) == 2
|
|
318
|
+
and [item.get("key") for item in records]
|
|
319
|
+
== sorted(item.get("key") for item in records)
|
|
320
|
+
and len({item.get("key") for item in records}) == 2
|
|
321
|
+
and all(
|
|
322
|
+
item.get("key") == item.get("value", {}).get("call_node_id")
|
|
323
|
+
and tuple(item.get("provenance", {}).get("evidence", ()))
|
|
324
|
+
== expected_provenance
|
|
325
|
+
for item in records
|
|
326
|
+
)
|
|
327
|
+
)
|
|
328
|
+
independent_valid, independent_reason = validate_keyword_call_binding_facts(
|
|
329
|
+
payload
|
|
330
|
+
)
|
|
331
|
+
direct = next(
|
|
332
|
+
(item for item in fact_values if item.get("keyword_names") == ["left", "flag", "ratio"]),
|
|
333
|
+
{},
|
|
334
|
+
)
|
|
335
|
+
reordered = next(
|
|
336
|
+
(item for item in fact_values if item.get("keyword_names") == ["ratio", "left", "flag"]),
|
|
337
|
+
{},
|
|
338
|
+
)
|
|
339
|
+
facts_valid = (
|
|
340
|
+
direct.get("source_to_parameter_ordinals") == [0, 1, 2]
|
|
341
|
+
and direct.get("parameter_to_source_ordinals") == [0, 1, 2]
|
|
342
|
+
and reordered.get("source_to_parameter_ordinals") == [2, 0, 1]
|
|
343
|
+
and reordered.get("parameter_to_source_ordinals") == [1, 2, 0]
|
|
344
|
+
and all(
|
|
345
|
+
fact.get("target_name") == "choose"
|
|
346
|
+
and fact.get("parameter_names") == ["left", "flag", "ratio"]
|
|
347
|
+
and fact.get("evaluation_order")
|
|
348
|
+
== fact.get("source_argument_node_ids")
|
|
349
|
+
and fact.get("arguments_evaluated_once") is True
|
|
350
|
+
and fact.get("parameter_coverage_exact") is True
|
|
351
|
+
and fact.get("lowering_shape") == KEYWORD_CALL_LOWERING_SHAPE
|
|
352
|
+
and fact.get("allocation_model") == "none"
|
|
353
|
+
and fact.get("cleanup_model") == "none"
|
|
354
|
+
and fact.get("runtime_binding_failure") == "proved-absent"
|
|
355
|
+
and fact.get("supported") is True
|
|
356
|
+
and fact.get("diagnostic_code") is None
|
|
357
|
+
for fact in fact_values
|
|
358
|
+
)
|
|
359
|
+
)
|
|
360
|
+
plans = [
|
|
361
|
+
item
|
|
362
|
+
for item in payload.get("rule_plans", ())
|
|
363
|
+
if item.get("rule_id") == KEYWORD_CALL_RULE_ID
|
|
364
|
+
]
|
|
365
|
+
plans_valid = (
|
|
366
|
+
len(plans) == 2
|
|
367
|
+
and {item.get("source_node_id") for item in plans}
|
|
368
|
+
== {item.get("call_node_id") for item in fact_values}
|
|
369
|
+
and all(
|
|
370
|
+
item.get("rule_version") == KEYWORD_CALL_RULE_VERSION
|
|
371
|
+
and item.get("support_state") == "SupportedDirect"
|
|
372
|
+
and item.get("helper_requirements") == []
|
|
373
|
+
and item.get("unresolved_obligations") == []
|
|
374
|
+
and item.get("resolved_obligations")
|
|
375
|
+
== item.get("semantic_obligations")
|
|
376
|
+
for item in plans
|
|
377
|
+
)
|
|
378
|
+
)
|
|
379
|
+
lowering_valid, lowering_evidence = _lowering_proof(payload, fact_values)
|
|
380
|
+
observer_valid = (
|
|
381
|
+
summary.get("rule_set_version") == PHASE14C_RULE_SET
|
|
382
|
+
and summary.get("renderer_version") == PHASE14C_RENDERER
|
|
383
|
+
and list(summary.get("keyword_calls", ())) == fact_values
|
|
384
|
+
and trace.get("trace_level") == "Full"
|
|
385
|
+
and trace.get("completeness") == "complete"
|
|
386
|
+
and trace.get("truncated") is False
|
|
387
|
+
and trace.get("observer_failed") is False
|
|
388
|
+
and [
|
|
389
|
+
item
|
|
390
|
+
for item in trace.get("rule_decisions", ())
|
|
391
|
+
if item.get("rule_id") == KEYWORD_CALL_RULE_ID
|
|
392
|
+
]
|
|
393
|
+
== plans
|
|
394
|
+
and all(
|
|
395
|
+
any(
|
|
396
|
+
mapping.get("rule_plan_id") == plan.get("plan_id")
|
|
397
|
+
for mapping in payload.get("source_output_mappings", ())
|
|
398
|
+
)
|
|
399
|
+
for plan in plans
|
|
400
|
+
)
|
|
401
|
+
)
|
|
402
|
+
helper_registry = default_helper_registry()
|
|
403
|
+
helper_valid = (
|
|
404
|
+
not payload.get("helper_manifest")
|
|
405
|
+
and not payload.get("helper_requirements")
|
|
406
|
+
and helper_registry.fingerprint
|
|
407
|
+
== "fcb719f07984f3b79e17262e90f93823a9a0139a60529f8486ab09f6c3663d98"
|
|
408
|
+
)
|
|
409
|
+
conformance = validate_c_text(accepted.generated_c or "")
|
|
410
|
+
deterministic = (
|
|
411
|
+
result_to_json(accepted) == result_to_json(repeated)
|
|
412
|
+
and accepted.request_fingerprint == repeated.request_fingerprint
|
|
413
|
+
and accepted.output_fingerprint == repeated.output_fingerprint
|
|
414
|
+
and accepted.stage_artifact.artifact_fingerprint
|
|
415
|
+
== repeated.stage_artifact.artifact_fingerprint
|
|
416
|
+
)
|
|
417
|
+
fresh_code = (
|
|
418
|
+
"import hashlib,json; from pycforge import ConversionRequest,PythonToCConverter; "
|
|
419
|
+
"from pycforge.converter.contracts.configuration import PHASE14C_RENDERER,PHASE14C_RULE_SET; "
|
|
420
|
+
"from pycforge.converter.core.request import ObservationOptions; "
|
|
421
|
+
"from pycforge.converter.core.serialization import result_to_json; "
|
|
422
|
+
f"s={source!r}; "
|
|
423
|
+
"r=PythonToCConverter().convert(ConversionRequest.from_source(s,rule_set_version=PHASE14C_RULE_SET,renderer_version=PHASE14C_RENDERER),observation=ObservationOptions('Full',False)); "
|
|
424
|
+
"print(json.dumps({'serialized_sha256':hashlib.sha256(result_to_json(r).encode()).hexdigest(),"
|
|
425
|
+
"'generated_sha256':hashlib.sha256((r.generated_c or '').encode()).hexdigest(),"
|
|
426
|
+
"'artifact_fingerprint':r.stage_artifact.artifact_fingerprint.value},sort_keys=True))"
|
|
427
|
+
)
|
|
428
|
+
env = {**__import__("os").environ, "PYTHONPATH": str(root)}
|
|
429
|
+
fresh = json.loads(
|
|
430
|
+
subprocess.check_output(
|
|
431
|
+
[sys.executable, "-c", fresh_code], cwd=root, env=env, text=True
|
|
432
|
+
)
|
|
433
|
+
)
|
|
434
|
+
fresh_expected = {
|
|
435
|
+
"serialized_sha256": hashlib.sha256(
|
|
436
|
+
result_to_json(accepted).encode()
|
|
437
|
+
).hexdigest(),
|
|
438
|
+
"generated_sha256": hashlib.sha256(
|
|
439
|
+
(accepted.generated_c or "").encode()
|
|
440
|
+
).hexdigest(),
|
|
441
|
+
"artifact_fingerprint": accepted.stage_artifact.artifact_fingerprint.value,
|
|
442
|
+
}
|
|
443
|
+
fresh_process_valid = fresh == fresh_expected
|
|
444
|
+
|
|
445
|
+
cross_request = ConversionRequest(
|
|
446
|
+
SourceBundle(
|
|
447
|
+
SourceDocumentInput("app.py", cross_primary, "app"),
|
|
448
|
+
(SourceDocumentInput("lib.py", cross_companion, "lib"),),
|
|
449
|
+
),
|
|
450
|
+
rule_set_version=PHASE14C_RULE_SET,
|
|
451
|
+
renderer_version=PHASE14C_RENDERER,
|
|
452
|
+
)
|
|
453
|
+
cross = converter.convert(cross_request, observation=observation)
|
|
454
|
+
cross_repeat = converter.convert(cross_request, observation=observation)
|
|
455
|
+
cross_payload = (
|
|
456
|
+
cross.stage_artifact.payload if cross.stage_artifact is not None else {}
|
|
457
|
+
)
|
|
458
|
+
cross_facts = (
|
|
459
|
+
_facts(cross_payload, KEYWORD_CALL_TABLE_ID) if cross_payload else []
|
|
460
|
+
)
|
|
461
|
+
cross_independent, cross_reason = (
|
|
462
|
+
validate_keyword_call_binding_facts(cross_payload)
|
|
463
|
+
if cross_payload
|
|
464
|
+
else (False, "cross-module conversion omitted its payload")
|
|
465
|
+
)
|
|
466
|
+
module_functions = (
|
|
467
|
+
{
|
|
468
|
+
item.get("value", {}).get("function_node_id"): item.get("value", {})
|
|
469
|
+
for item in _table(
|
|
470
|
+
cross_payload, "module-function-facts"
|
|
471
|
+
).get("records", ())
|
|
472
|
+
}
|
|
473
|
+
if cross_payload
|
|
474
|
+
else {}
|
|
475
|
+
)
|
|
476
|
+
cross_lowering, cross_lowering_evidence = _lowering_proof(
|
|
477
|
+
cross_payload, cross_facts
|
|
478
|
+
)
|
|
479
|
+
cross_fact = cross_facts[0] if len(cross_facts) == 1 else {}
|
|
480
|
+
cross_valid = (
|
|
481
|
+
cross.status is ResultStatus.CONVERTED
|
|
482
|
+
and cross.stage_artifact is not None
|
|
483
|
+
and cross.stage_artifact.schema_version == "0.14.2"
|
|
484
|
+
and cross_payload.get("rule_set_version") == PHASE14C_RULE_SET
|
|
485
|
+
and cross_payload.get("renderer_version") == PHASE14C_RENDERER
|
|
486
|
+
and len(cross_facts) == 1
|
|
487
|
+
and cross_fact.get("source_to_parameter_ordinals") == [2, 1, 0]
|
|
488
|
+
and cross_fact.get("parameter_to_source_ordinals") == [2, 1, 0]
|
|
489
|
+
and module_functions.get(
|
|
490
|
+
cross_fact.get("target_function_node_id"), {}
|
|
491
|
+
).get("module_id")
|
|
492
|
+
== "lib"
|
|
493
|
+
and (cross.conversion_summary or {})
|
|
494
|
+
.get("module_initialization", {})
|
|
495
|
+
.get("module_order")
|
|
496
|
+
== ["lib", "app"]
|
|
497
|
+
and cross_independent
|
|
498
|
+
and cross_lowering
|
|
499
|
+
and result_to_json(cross) == result_to_json(cross_repeat)
|
|
500
|
+
and validate_c_text(cross.generated_c or "").accepted
|
|
501
|
+
and not cross_payload.get("helper_manifest")
|
|
502
|
+
)
|
|
503
|
+
|
|
504
|
+
rejected = {
|
|
505
|
+
label: converter.convert(phase14c_request(text))
|
|
506
|
+
for label, (_, text) in rejections.items()
|
|
507
|
+
}
|
|
508
|
+
rejection_codes = {
|
|
509
|
+
label: [item.code for item in result.diagnostics]
|
|
510
|
+
for label, result in rejected.items()
|
|
511
|
+
}
|
|
512
|
+
rejections_valid = all(
|
|
513
|
+
result.status is ResultStatus.REJECTED
|
|
514
|
+
and rejection_codes[label] == [expected_code]
|
|
515
|
+
and result.generated_c is None
|
|
516
|
+
and result.output_fingerprint is None
|
|
517
|
+
and result.stage_artifact is not None
|
|
518
|
+
and "c_ir" not in result.stage_artifact.payload
|
|
519
|
+
and "helper_manifest" not in result.stage_artifact.payload
|
|
520
|
+
for label, (expected_code, _) in rejections.items()
|
|
521
|
+
for result in (rejected[label],)
|
|
522
|
+
)
|
|
523
|
+
|
|
524
|
+
historical_source = (
|
|
525
|
+
"def choose(left: int, flag: bool) -> int:\n return left\n\n"
|
|
526
|
+
"def run(value: int, flag: bool) -> int:\n"
|
|
527
|
+
" return choose(flag=flag, left=value)\n"
|
|
528
|
+
)
|
|
529
|
+
historical = converter.convert(
|
|
530
|
+
ConversionRequest.from_source(
|
|
531
|
+
historical_source,
|
|
532
|
+
rule_set_version=PHASE14B_RULE_SET,
|
|
533
|
+
renderer_version=PHASE14B_RENDERER,
|
|
534
|
+
),
|
|
535
|
+
observation=observation,
|
|
536
|
+
)
|
|
537
|
+
historical_payload = (
|
|
538
|
+
historical.stage_artifact.payload
|
|
539
|
+
if historical.stage_artifact is not None
|
|
540
|
+
else {}
|
|
541
|
+
)
|
|
542
|
+
phase14b_exact = (
|
|
543
|
+
historical.status is ResultStatus.REJECTED
|
|
544
|
+
and [item.code for item in historical.diagnostics] == ["PYC2910"]
|
|
545
|
+
and [item.diagnostic_id for item in historical.diagnostics]
|
|
546
|
+
== ["diag-33b10f68721e38b3e960"]
|
|
547
|
+
and historical.request_fingerprint is not None
|
|
548
|
+
and historical.request_fingerprint.value
|
|
549
|
+
== "c447d082bb1b12228b0e7fd80ed17c438063f0591ffee2b4b240031fc6d9187f"
|
|
550
|
+
and historical.stage_artifact is not None
|
|
551
|
+
and historical.stage_artifact.kind == "conversion_plan"
|
|
552
|
+
and historical.stage_artifact.schema_version == "0.14.1"
|
|
553
|
+
and historical.stage_artifact.artifact_fingerprint.value
|
|
554
|
+
== "8daf5c369e7ea4e61521bebbae32efccd4ede450e375b09bc44f37ed9d0540c5"
|
|
555
|
+
and historical_payload.get("schema_version") == "conversion-plan/0.14.1"
|
|
556
|
+
and (historical.conversion_summary or {}).get("schema_version")
|
|
557
|
+
== "pycforge.conversion-summary/0.14.1"
|
|
558
|
+
and (historical.decision_trace or {}).get("schema_version")
|
|
559
|
+
== "pycforge.decision-trace/0.14.1"
|
|
560
|
+
and KEYWORD_CALL_TABLE_ID
|
|
561
|
+
not in {
|
|
562
|
+
item.get("table_id")
|
|
563
|
+
for item in historical_payload.get("fact_tables", ())
|
|
564
|
+
}
|
|
565
|
+
and historical.generated_c is None
|
|
566
|
+
and historical.output_fingerprint is None
|
|
567
|
+
)
|
|
568
|
+
|
|
569
|
+
passed = all(
|
|
570
|
+
(
|
|
571
|
+
identity_valid,
|
|
572
|
+
constants_valid,
|
|
573
|
+
table_valid,
|
|
574
|
+
independent_valid,
|
|
575
|
+
facts_valid,
|
|
576
|
+
plans_valid,
|
|
577
|
+
lowering_valid,
|
|
578
|
+
observer_valid,
|
|
579
|
+
helper_valid,
|
|
580
|
+
conformance.accepted,
|
|
581
|
+
deterministic,
|
|
582
|
+
fresh_process_valid,
|
|
583
|
+
cross_valid,
|
|
584
|
+
rejections_valid,
|
|
585
|
+
phase14b_exact,
|
|
586
|
+
)
|
|
587
|
+
)
|
|
588
|
+
return {
|
|
589
|
+
"audit": "keyword",
|
|
590
|
+
"passed": passed,
|
|
591
|
+
"active_contracts": active_contracts,
|
|
592
|
+
"active_contract_identities_valid": identity_valid,
|
|
593
|
+
"keyword_rule_id": KEYWORD_CALL_RULE_ID,
|
|
594
|
+
"keyword_rule_version": KEYWORD_CALL_RULE_VERSION,
|
|
595
|
+
"keyword_fact_schema": KEYWORD_CALL_FACT_SCHEMA,
|
|
596
|
+
"keyword_contract_constants_valid": constants_valid,
|
|
597
|
+
"keyword_fact_count": len(fact_values),
|
|
598
|
+
"keyword_fact_table_valid": table_valid,
|
|
599
|
+
"independent_fact_and_plan_validation": independent_valid,
|
|
600
|
+
"independent_validation_message": independent_reason,
|
|
601
|
+
"direct_source_to_parameter_ordinals": direct.get(
|
|
602
|
+
"source_to_parameter_ordinals"
|
|
603
|
+
),
|
|
604
|
+
"direct_parameter_to_source_ordinals": direct.get(
|
|
605
|
+
"parameter_to_source_ordinals"
|
|
606
|
+
),
|
|
607
|
+
"reordered_source_to_parameter_ordinals": reordered.get(
|
|
608
|
+
"source_to_parameter_ordinals"
|
|
609
|
+
),
|
|
610
|
+
"reordered_parameter_to_source_ordinals": reordered.get(
|
|
611
|
+
"parameter_to_source_ordinals"
|
|
612
|
+
),
|
|
613
|
+
"keyword_facts_valid": facts_valid,
|
|
614
|
+
"keyword_rule_plan_count": len(plans),
|
|
615
|
+
"keyword_rule_plans_valid": plans_valid,
|
|
616
|
+
"source_order_staging_and_formal_reference_permutation_valid": lowering_valid,
|
|
617
|
+
"lowering_evidence": lowering_evidence,
|
|
618
|
+
"observer_evidence_valid": observer_valid,
|
|
619
|
+
"helper_manifest_empty": not payload.get("helper_manifest"),
|
|
620
|
+
"helper_registry_fingerprint": helper_registry.fingerprint,
|
|
621
|
+
"helper_contract_unchanged": helper_valid,
|
|
622
|
+
"allocation": "none",
|
|
623
|
+
"cleanup": "none",
|
|
624
|
+
"runtime_binding_failure": "proved-absent",
|
|
625
|
+
"generated_c_conformance": conformance.accepted,
|
|
626
|
+
"deterministic": deterministic,
|
|
627
|
+
"fresh_process_deterministic": fresh_process_valid,
|
|
628
|
+
"serialized_sha256": fresh_expected["serialized_sha256"],
|
|
629
|
+
"generated_c_sha256": fresh_expected["generated_sha256"],
|
|
630
|
+
"cross_module_valid": cross_valid,
|
|
631
|
+
"cross_module_source_to_parameter_ordinals": cross_fact.get(
|
|
632
|
+
"source_to_parameter_ordinals"
|
|
633
|
+
),
|
|
634
|
+
"cross_module_parameter_to_source_ordinals": cross_fact.get(
|
|
635
|
+
"parameter_to_source_ordinals"
|
|
636
|
+
),
|
|
637
|
+
"cross_module_target_module": module_functions.get(
|
|
638
|
+
cross_fact.get("target_function_node_id"), {}
|
|
639
|
+
).get("module_id"),
|
|
640
|
+
"cross_module_order": (cross.conversion_summary or {})
|
|
641
|
+
.get("module_initialization", {})
|
|
642
|
+
.get("module_order"),
|
|
643
|
+
"cross_module_independent_validation": cross_independent,
|
|
644
|
+
"cross_module_independent_validation_message": cross_reason,
|
|
645
|
+
"cross_module_lowering_evidence": cross_lowering_evidence,
|
|
646
|
+
"rejection_case_count": len(rejections),
|
|
647
|
+
"rejection_codes": rejection_codes,
|
|
648
|
+
"rejections_exact_and_publish_no_c": rejections_valid,
|
|
649
|
+
"phase14b_exact_keyword_rejection": phase14b_exact,
|
|
650
|
+
"python_subprocess_used_for_determinism_only": True,
|
|
651
|
+
"c_toolchain_invoked": False,
|
|
652
|
+
"generated_c_compiled_or_executed": False,
|
|
653
|
+
}
|
|
654
|
+
except Exception as exc:
|
|
655
|
+
return {
|
|
656
|
+
"audit": "keyword",
|
|
657
|
+
"passed": False,
|
|
658
|
+
"error": f"{type(exc).__name__}: {exc}",
|
|
659
|
+
"c_toolchain_invoked": False,
|
|
660
|
+
"generated_c_compiled_or_executed": False,
|
|
661
|
+
}
|