fix(tier3): decode native Codex exec calls - #111
Conversation
Signed-off-by: Tomas <180413002+Tomauskasz@users.noreply.github.com>
766936e to
c33cce5
Compare
Context: Native Codex exec wrappers can contain unsupported, unobserved, or ambiguous inner tool calls. Normalize those calls before Tier 3 checks so collectors do not treat missing execution evidence as a successful inner call. Changes: - Add one dependency-free Codex tool-call normalizer for the package evaluator and copied Harbor verifier. - Keep unsupported wrappers atomic with an explicit unsupported_native_codex_exec_wrapper status, and assign wrapper observations only to uniquely rendered inner calls. - Add stable inner evidence_id values for deduplication, report lookup, Rich rendering, and suggestion grounding. - Reject unsupported execution evidence across activation, script, workflow, negative-case, routing, efficiency, recovery, and security checks while preserving generic non-Codex exec calls. - Expand regression coverage and record the release impact in the changelog. Impact: Tier 3 now distinguishes observed inner calls from unobserved, ambiguous, and unsupported native Codex wrappers. Reports and suggestions reference the correct normalized evidence, and the standalone verifier uses the same parser as package evaluations. Validation: - Focused tests: 78 passed. - Tier 3 suite: 664 passed. - Full suite: 5222 passed, 17 skipped, 4 deselected. - Lint: all checks passed. - Build: created the source archive and wheel, including codex_tool_call_normalizer.py. - git diff --check: passed. Notes: Generic exec calls without a string arguments.input remain unchanged for non-Codex compatibility. This repository has no PR CI configured. Signed-off-by: Tomas <180413002+Tomauskasz@users.noreply.github.com>
|
End-to-end follow-up:
This closes the installed-runtime proof gap for the PR. No additional PR change was required. |
rng1995
left a comment
There was a problem hiding this comment.
The Codex normalization needs one compatibility guard before this can merge.
| arguments = tool_call.get("arguments") or {} | ||
| if not isinstance(arguments, dict) or not isinstance(arguments.get("input"), str): | ||
| return [tool_call] | ||
| parsed = _static_codex_tool_calls(arguments["input"]) |
There was a problem hiding this comment.
This classifies every tool named exec with a string arguments.input as native Codex. A generic ATIF call such as {"function_name":"exec","arguments":{"input":"list repository files"}} is now marked unsupported and makes deterministic checks unscorable. Gate this on Codex provenance or a definitive wrapper signature; otherwise preserve the generic call atomically, with a regression.
There was a problem hiding this comment.
Addressed in d102471. Generic ATIF exec calls with string input now remain atomic unless parsing succeeds or the input carries a definitive Codex wrapper signature: a valid first-line // @exec: pragma or a tools wrapper reference. Malformed signed wrappers still fail closed. The exact reviewer case passes in both the shared and packaged verifier extractors.
Verification: exact regression 2 passed; full normalization module 65 passed; narrow downstream Tier 3 consumers 81 passed; full suite 5,312 passed, 17 skipped, and 4 deselected; full Ruff passed; source and wheel builds passed; git diff --check passed.
Fresh CI, DCO, and Security runs were created, but GitHub marked them action_required before running. The contributor account cannot approve fork workflows, so they are waiting for maintainer approval.
|
@Tomauskasz Gentle ping when you have a chance: the remaining compatibility review thread is still waiting for an update or response. Thank you for your patience throughout the review and for your contribution. |
Yeah okay, I'll get back to this soon when I can |
Context: The normalizer treated every `exec` call with string `arguments.input` as native Codex evidence. ATIF permits generic input payloads, and the normalizer does not receive trajectory-level agent provenance. Changes: - Preserve unparsable `exec` input atomically unless the source contains a first-line Codex pragma or a `tools` wrapper reference. - Reuse the pragma pattern in parsing and signature detection. - Add the generic ATIF input regression to the shared and packaged verifier extractors. Impact: Generic `exec` input remains scorable as its original atomic call. Malformed or unsupported inputs with a native Codex signature continue to fail closed. Validation: - Exact generic-input regression: 2 passed. - Full Codex normalization test module: 65 passed. - Narrow downstream Tier 3 consumer tests: 81 passed. - Ruff lint and format checks: passed. - `git diff --check`: passed. Notes: The full repository suite and a captured real Codex trajectory replay were not run locally. Signed-off-by: Tomas <180413002+Tomauskasz@users.noreply.github.com>
Context: Generic ATIF exec input containing bare prose such as a sentence-ending `tools.` was still classified as an unsupported native Codex wrapper. Require a complete tool-member call signature before applying the fail-closed native-wrapper status. Changes: - Match direct and quoted computed-property tool members only when followed by call syntax. - Preserve the existing escaped-parenthesis signature used by regex-literal wrapper evidence. - Extend the shared and packaged extractor regression matrix with sentence-ending and property-name prose. Impact: Generic exec calls remain atomic when their input only mentions tools in prose. Valid native Codex calls and malformed inputs containing complete wrapper signatures retain their existing normalization behavior. Validation: - `uv run pytest -q tests/tier3/test_codex_tool_call_normalization.py`: 69 passed. - `uv run pytest -q`: 5316 passed, 17 skipped, 4 deselected. - `uv run ruff check src tests`: passed. - `uv build`: source archive and wheel built successfully. - `git diff --check`: passed. Notes: The repository-wide formatter check remains red on pre-existing files and is not part of the configured Makefile lint target.
|
Follow-up from the complete three-lane review is in 734f8e7. The definitive Codex-signature guard now requires a tool member followed by call syntax. Generic ATIF prose such as Verification:
|
Context: Native Codex exec normalization now bounds parser work, reserves internal ATIF metadata, and preserves opaque outer observations for unsupported wrappers. Tier 3 evidence consumers now resolve one stable identity in evidence_id, json_pointer, then path order. Changes: - Cap wrapper input at 64 KiB, object nesting at 64 containers, parsed statements at 256, and inner tool calls at 128. - Strip caller-supplied _atif_* fields before normalization, centralize normalized traversal and observation ownership, and scan unsupported-wrapper observations for secrets. - Add a shared evidence-reference identity helper for report rendering, deduplication, Harbor prompts and lookup, and the standalone verifier. - Copy the normalizer and evidence helper with Harbor verifier tasks and add shared, standalone, packaging, parser-boundary, security, and reporting regressions. Impact: Forged normalization metadata cannot suppress destructive-command or secret-exposure findings. Oversized or unsupported wrappers fail closed without interpreting arbitrary JavaScript. Normalized, pointer-only, and path-only evidence references retain stable distinct identities across reports and remediation suggestions. Validation: - Full suite: 5,339 passed, 17 skipped, 4 deselected. - Focused normalization and suggestion suite: 99 passed. - Ruff lint: passed. - Source distribution and wheel build: passed. - Wheel content check: skillevaluator/evidence.py present. - git diff --check: passed. - Independent follow-up review: no findings. Notes: Unsupported JavaScript remains uninterpreted. Parser ceilings are fixed trust-boundary limits. Signed-off-by: Tomas <180413002+Tomauskasz@users.noreply.github.com>
|
Additional hardening from the final re-review is in 23f2348.
The exact forged-metadata, oversized-prefix, whitespace-fallback, shared-verifier, and standalone-verifier counterexamples now pass. Final verification: 5,339 passed, 17 skipped, 4 deselected; Ruff passed; source and wheel builds passed; Fresh CI, DCO, and Security runs were created for this head. GitHub marked them |
|
Updated the branch from current Post-update verification on the exact merged head:
Fresh CI, DCO, and Security runs were created for this merged head. GitHub marked them |
Summary
Normalize native Codex custom
exectrajectories before Tier 3 deterministic checks and evidence compilation.Codex records native tool calls inside JavaScript in
exec.arguments.input. This change adds one dependency-free parser shared by package evaluations and the copied standalone Harbor verifier. The adapter stages the parser and shared evidence helper beside the verifier template.The normalizer preserves execution uncertainty instead of manufacturing successful inner calls:
normalization_status = "unsupported_native_codex_exec_wrapper";_atif_*fields are removed before normalization so raw input cannot forge internal status or ownership metadata;unobserved_inner_call;execcalls without stringarguments.inputremain unchanged.Parser work is bounded to 64 KiB of source, 64 nested JSON containers, 256 statements, and 128 inner tool calls. Invalid JSON resource states and inputs beyond those ceilings fail closed as unsupported wrappers before unbounded signature scans.
Every normalized inner call receives a stable
evidence_id. One shared identity rule usesevidence_id, thenjson_pointer, thenpathafter trimming each candidate. Deduplication, aggregate and Markdown reports, Harbor rendering, suggestion prompts and lookup, and the standalone verifier use that rule while rawjson_pointervalues continue to reference the real outer ATIF call.Unsupported execution evidence fails closed across activation, script, workflow-order, negative-case, routing, tool-efficiency, error-recovery, and security checks. Regression coverage includes supported, unsupported, dead, malformed, mixed, rendered, unrendered, ambiguous, repeated-render, generic non-Codex, parser-limit, private-metadata collision, evidence-cardinality, path-only, whitespace-fallback, and public-metadata cases. Arbitrary JavaScript is not scanned as shell text.
Fixes #110.
Verification
Focused normalization and suggestion tests:
99 passedFull suite after updating from
main:5562 passed, 17 skipped, 4 deselectedLint:
All checks passedBuild: source archive and wheel built successfully; the wheel includes
codex_tool_call_normalizer.pyandevidence.pygit diff --check: passedIndependent follow-up review: no findings
I am familiar with the Contributing Guidelines
Added or updated focused tests
Updated documentation for user-visible changes
Ran
make lintRan the full test suite
Ran
make buildDid not add credentials, private datasets, or proprietary benchmark content
Release Impact
CHANGELOG.md