Skip to content

Prepare fresh functional wheel targets through the runtime owner - #3825

Merged
trissim merged 15 commits into
mainfrom
fix/isolated-runtime-inputs
Nov 2, 2026
Merged

trissim merged 15 commits into
mainfrom
fix/isolated-runtime-inputs

Conversation

@trissim

@trissim trissim commented Nov 1, 2026 •

Copy link
Copy Markdown
Contributor

Current delivery: f8c0d10

15 commits; 18 changed files; +928/-103.

Runtime ownership

Before: package capture, resolution capture, launch path and proof ancestry could
answer overlapping build questions independently. After: RuntimeStack owns one
RuntimeResolutionProbe; InterpreterBuildProbe and package-source behavior supply
its independently typed evidence. BuildArtifact shares same-open-handle identity
and byte capture between native images and wheel inputs. Linux resolves the
symbol's actual mapping, including shared libpython, rather than mutable argv.

Production-lock cache eligibility and recorded completion are separate questions.
WheelRuntime inherits preparation, completion and retirement for fresh explicit
inputs; its retained wheels are immutable inputs, not invented Git origins.
RecordedBuildIdentity requires recorded interpreter evidence before certifying an
installed proof. ArchiveRecord owns local URL decoding; ArchiveInfo owns digest
verification. The temporary URL enums and forwarding route are deleted.

The current-base rebase onto5a8141b3a leaves all15 authored commits unchanged by
range-diff. The exact-head source verdict is recorded. Hosted checks, queue entry,
merge and installation remain forge/runtime observations, not claims made by this
body. The historical33/33 controls and real private-copy carry below retain their
original source heads; they were not rerun merely to qualify this rebase.

Assumed: supported explicit wheels use root layout; remote archive URLs retain
metadata without fetching. Module origins are provenance, not loaded-code hashes.
The requested interpreter and native assets must satisfy their actual owners.

Historical implementation and evidence: original heads and scopes retained

Current delivery: e023196

15 commits;18 changed files,+928/-103. The published source has green ready,
base, native-scripts, review-verdict, debt-src and debt-tools checks. Auto-merge
was enabled for this exact head. Merge and installation are recorded separately.

Final owner corrections

  • ArchiveInfo owns PEP610 hash verification: an absent digest supplies no
    constraint; a supplied digest must match the observed artifact. The resulting
    archive info is assigned through its declared field rather than a string-keyed
    model_copy update.
  • ArchiveRecord owns URL-to-wheel decoding directly. Its old forwarding path
    through ArchiveInfo and three interim enums are deleted. The external file
    scheme, local authorities and wheel suffix are declared on this boundary.
    Missing-hash, non-file, non-wheel, foreign-host, relative-path and malformed
    digest behavior follows the existing guards in the same order.
  • LinuxPlatform normalizes the foreign C null pointer at its native-image
    boundary before enforcing the nonzero-address requirement.
  • RuntimeStack's build-resolution observation uses the shared RuntimeProbe owner;
    RuntimeResolution.capture's competing path is deleted. Artifact observation
    shares the open-stream identity/bytes owner for interpreter and wheel inputs.

The earlier sections retain their original execution heads and artifacts. The
33/33 Core controls and private-copy carry below are historical evidence at their
recorded sources, not newly executed e023 results. Current hosted checks and the
final source trace establish the final owner corrections; physical application
and installed evidence remain separate. A test title or a manifest alone does
not establish a working installation.

Assumed: PEP610's local file URL vocabulary is the external boundary contract;
remote URLs are metadata, not permission to fetch them. Loaded-module origins
are not hashes of already-loaded code. Native image identity and content are
observed from their actual opened resource, rather than inferred from a launch
pathname or package version.


Earlier implementation and evidence, with original scopes

Real target-worker and frontend admission epoch (1408 build01 / capture13)

The published Core94631c18e0 source was built as an exact wheel (SHA25669906e982e0429218ebe32d921e3e36ce8be5d1491693674aa7bd8be5e797c65) beside Toad1408/d34's exact wheel. The existing WheelRuntime owner prepared a NEW immutable prefix from the recorded f03 dependency runtime and stock3.14.8 interpreter. Producer digests, native preparation, package preparation, runtime-resolution and client-import probes completed in target workers; the worker lifetime and host lease closed. Build output is retained in capture-1408-build-01 under the Performance scratch owner.

Capture13 then started the actual Toad CLI from that prefix in isolated plain st/Xvfb. Its strict AdmitOperation re-observed and accepted the real frontend: process1582313/birth641126598, Core/Toad/Textual module paths inside the prefix, exact retained wheel hashes, recorded invoked interpreter, ABI/stdlib and native disk-artifact SHA25628299dda2e5c8572d39821fee8552b543dfadc4681a4c4d0b03c69e56d7f9d66. The actual frontend/build-admitted.json is retained, not reconstructed from the preparation result. This is a real strict-entry result, not merely import/model proof, and remains distinct from native model or physical scenario acceptance.

Capture12 had already refused a foreign inherited launcher before any frontend/input; its failure remains. Capture13 displayed saved history but its source-created owner had been stopped before retargeting, so Toad correctly opened a read-only stopped thread and never reached ACP Ready. No provider input was sent. The frontend/display/private copy retired. Fresh14 uses the existing owner lifecycle to start the private thread on the selected target after the installed source owner forks and stops it; no result from that ongoing run is claimed in this paragraph. Native validation is not weakened.

These observations do not establish full carry/rehearsal, repository ancestry from archive hashes, loaded-code memory equivalence, cached-runtime reuse on a different interpreter, Darwin support, completed provider response or latency. Actual source/runtime identities and failed epochs remain separate. Existing58 source-model passes belong to run14, not these physical stages.


Current source checkpoint 94631c18e04a168c48293073bc93fef40b1eb050

12 commits; 18 files, +919/-101 against origin/main. Rebased over test cleanup58daba13e and the installed f03ec97 line; main's deleted tests were not restored. Local, remote and forge head match; OPEN/non-draft.

Affected execution14 actually completed under the existing host TestLease, using separate repository pytest processes/configurations: Core33/33 passed in12.85s; Toad25/25 passed in1.01s; controller rc0. Selection: Core tests/test_runtime_resolution.py, tests/test_proof_build.py; Toad tests/model/test_physical_run.py. Logs and input hashes: /home/ts/.cache/agent-scratch/pi-ui-performance/runtime-observer-14-*.

The latest fixture correction uses the holder's genuine self-order for successive proof scenarios and the current broad HeldOrders.read contract. Strict runtime/image admission is unchanged. Earlier setup failures and run12/13 reds remain retained; their results are not relabeled as current passes.

This is source-selected contract evidence, not a new installed Core3825 runtime, real-data carry, native-provider response, physical paint or latency result. Those delivery obligations remain open. Assumed: the exercised source-selection namespace and declared shared dev environment are the stated test scope; synthetic fixture manifests do not qualify real installed bytes.

All older heads/counts below are retained historical epochs, not current-head evidence.

What this fixes

An isolated runtime must run the exact interpreter and package bytes supplied to it. Previously preparation could resolve different package inputs, completion could omit interpreter identity, and the final admission probe could mistake the title toad for Python's native filename. The added interpreter models also exposed a schema-dispatch hole in the native tool catalog.

11 commits, 18 files, +914/-98 against origin/main at publication. Latest source correction: 9 files, +97/-92 before rebase. Head dc44cd1177f509b1885f378b5d1c7a2ad2b33f44; rebased onto main 4d3a1c083. This is the exact-input/runtime repair, separate from paint PR toad#1399 and physical harness PR toad#1393.

Interpreter and file identity

Before:

  • Completion identified repository commits but not the Python implementation executing the proof.
  • dladdr(Py_GetVersion).filename was treated as an immutable pathname. On this Linux interpreter it aliases argv storage: ApplicationLifetime.set_process_title("toad") changes that filename to literal toad while the actual native mapping stays unchanged.
  • A native file located by one mechanism was reopened by another before hashing.

After:

  • InterpreterBuildProbe records invoked interpreter, version, ABI, stdlib and native/executable artifacts.
  • Existing Platform owns symbol-image acquisition. Its Linux implementation locates the address in /proc/self/maps, resolves the corresponding map_files target, opens it, and checks its descriptor's device/inode against the kernel mapping.
  • BuildArtifact.from_stream hashes that qualified handle and checks file revision during capture and pathname identity afterward. Ordinary path capture uses the same implementation.
  • Shared libpython is supported: the image providing the actual symbol is not assumed to be the executable. Missing, replaced or anonymous/unavailable native files fail rather than receive invented identity.
  • The former PythonNativeImage pathname authority is deleted. The ABI structure lives with the platform loader operation; Linux does not use the mutable loader filename.

The real before/after title-mutation control passes even with a fake file named toad in the working directory. A real shared-library symbol is captured; atomic replacement of an owned loaded library and a null address are refused. Darwin's loader path is not exercised by these Linux controls.

Exact package preparation

ArchivePin / ArchiveRecord retain the supplied archive's identity. Package probes compare installed members against that archive rather than treating a matching package name/version as proof of matching bytes. RuntimeResolution and RuntimeStack carry these declared inputs through the existing UV/native preparation path; the prepare-runtime command exposes that path without a parallel installer.

Unchanged dependencies/native inputs remain reusable. Changed wheel inputs require a new target prefix. Existing borrowed prefixes and hardlinked/shared wheel members are not modified to manufacture a passing result.

Completion cannot omit the interpreter

build_identity.py, the order completion producer and its fixtures carry the interpreter observation through the existing recorded proof-build representation. Missing proof and mismatched installed package identity refuse completion. This is not a second writable runtime ledger or an opaque success marker.

The test fixtures now construct the same declared records as production rather than patching product methods to bypass these requirements.

Cache eligibility is not proof admission

The real #3850 rehearsal against the installed2b89 build reached RuntimeResolution.matches and raised on its absent interpreter observation. That question asks whether the old prefix is reusable, not whether missing evidence can certify it.

InterpreterBuild.matches(actual) now answers False; RecordedInterpreterBuild compares the actual observed interpreter. RuntimeResolution delegates to that family answer. require_runtime and recorded proof admission remain strict and unchanged. No compatibility conversion or invented observation is added.

test_unrecorded_interpreter_is_not_a_runtime_cache_match exercises the real RuntimeStack/probe path and the recorded equal/changed cases. This new regression is UNRUN by the author; the commander owns the repeated rehearsal.

Source ownership and stream corrections

Before: installed-package probes lived beside the records they consumed and imported the higher resolution owner locally. RuntimeResolution imported its own observer locally. The retained-wheel destination reused a set-valued variable, and external stream/path annotations did not establish the APIs actually called.

After:

  • probes/packages.py keeps package records and the distribution inventory. InstalledPackagesProbe and WheelPackagesProbe move directly into existing probes/resolution.py, beside the aggregate probe. Names, fields and TargetProbe MRO remain unchanged; no re-export is retained.
  • RuntimeStack.observe_resolution owns worker orchestration. Unbuilt completion, recorded completion and tools/checker_stack.py use it directly. ProjectMetadata stays at its existing owner; no parser or metadata record is copied.
  • Native-image acquisition and BuildArtifact use the actual BufferedReader contract. Hashing still consumes the same already-open handle, with both revision checks unchanged.
  • Installed distribution locations must be filesystem Paths; ZIP member streams are qualified as ZipExtFile at the external boundary. Neither path is converted through a string or reopened to satisfy typing.
  • The canonical-name inventory explicitly declares its string-keyed dictionary contract. Retained-wheel destinations no longer reuse the package-name set variable. The two reported wording sites are corrected without whole-file formatting.

Before/after actual encoded ProbeRequests for both moved probes are byte-identical and round-trip at both revisions. Evidence under /home/ts/.cache/agent-scratch/pi-ui-performance/: runtime-requests-before.json, runtime-requests-after.json, runtime-requests-compare.log (rc0). This data-only result does not run a donor worker or certify its refusals.

All nine changed Python files parse, and diff whitespace checks pass. The targeted seven-file mypy command is not green: 35 errors remain in child_process.py and tools/checker_stack.py, including unavailable tool imports; none were reported in the five other selected modules or the changed native-image declarations. Full output is runtime-owner-types.log. No author pytest or local NRA gate ran. Integration retains actual donor observation, wheel-member refusal, recorded/equal/changed interpreter, native title-mutation and supported rehearsal qualification.

Pydantic schemas use their existing decoder

Before: _PydanticDecoder already implemented model encode/decode, but final schema dispatch asked the represented decoder class for a schema without its target. The interpreter models nested under CommsOrderDoneTool.delivery reached _OpaqueDecoder, breaking one of the 65 native tool declarations.

After:

  • ValueDecoder.value_schema() supplies the default class schema.
  • Final structural schema dispatch asks the compiled decoder for its value schema.
  • _PydanticDecoder declares its existing BaseModel capability once, owns model_json_schema(by_alias=True, mode="validation"), and gives that schema its own resource ID so nested $defs / $ref resolve inside the model.
  • The separate BaseModel branch in compile_decoder is deleted.

No tool, interpreter field, delivery alternative or model contract is removed or narrowed. No compatibility alias or opaque fallback is added.

Evidence

Latest source controls, retained under /home/ts/.cache/agent-scratch/pi-ui-performance/:

  • interpreter-repair-controls.log: real title mutation, shared-library image capture, replaced/null-image refusal; all 65 native tool schemas; 2 interpreter model roundtrips and 1 recursive nested model/dataclass roundtrip.
  • interpreter-schema-references.log: existing OpenHCS Python3.12 jsonschema / referencing validates generated DATA only: 69 schemas, 20 resolved references, 3 accepted payloads, 1 rejected invalid recursive payload. No additional environment or package installation.
  • The commander reports 115 cases passed in the combined selection before the latest rehearsal correction. The real rehearsal then exposed the cache-eligibility failure above. The three latest changed files compile; the new cache-match regression and repeated rehearsal remain commander-owned and are not claimed passed here.
  • The six changed files retain identical hashes through the final rebase. Native build input validation passes for 62 inputs.
  • Scoped NRA source map: 66 modules, 1,407 canonical classes, 0 parse omissions; raw classes 1,467→1,470, sites 34,375→34,462. The 63 unprojected/local cases and dynamic/effect/foreign-platform/movement limits remain unresolved, not scored as a universal proof.

Earlier exact-input preparation evidence remains at its recorded revisions: a private installed WHEEL replacement was refused without changing shared inputs; historical carry replay reported 22 already-current steps and zero pending changes. Those runs are not relabelled as this head's installed acceptance.

Delivery boundary

The two reproduced startup blockers are repaired in source and pushed for review. A newly built prefix and the configured active-agent physical capture still follow; the old immutable0402/3475 prefix is not overwritten. Production integration/installation belongs to the commander. The paint fix remains independently deliverable on toad#1399.

Assumed: Linux kernel mapping metadata identifies the file backing the captured symbol; existing supported package/UV/native owners remain the preparation authority; a missing backing file is a refusal, not a fallback. No claim is made that the unfinished physical workflow passed.

Copilot AI balanced review requested due to automatic review settings November 1, 2026 04:54

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has insufficient remaining quota. Try requesting a review at a lower effort level.

An organization owner can choose the repository organization as the billing source for reviews requested by members with a paid Copilot license. Learn about Copilot code review billing.

@github-actions

github-actions Bot commented Nov 1, 2026 •

Copy link
Copy Markdown

debt-tools at f8c0d10 passes.

@trissim
trissim force-pushed the fix/isolated-runtime-inputs branch 2 times, most recently from 1b36bc4 to 4e50f7a Compare November 1, 2026 06:48
@github-actions

github-actions Bot commented Nov 1, 2026 •

Copy link
Copy Markdown

debt-src at f8c0d10 passes.

Warn-only, never blocks (14)
src/agent_comms/child_process.py: LintFindings +2
src/agent_comms/installer/probes/interpreter.py: LintFindings +1
src/agent_comms/installer/runtime_stack.py: LintFindings +2
src/agent_comms/cli_verbs/prepare_runtime.py: Unformatted +1
src/agent_comms/installer/probes/interpreter.py: Unformatted +1
src/agent_comms/installer/probes/packages.py: Unformatted +1
src/agent_comms/installer/probes/resolution.py: Unformatted +1
found LintFindings:src/agent_comms/child_process.py at src/agent_comms/child_process.py:43 (F401 [*] `typing.BinaryIO` imported but unused) src/agent_comms/child_process.py:1302 (E501 Line too long (104 > 100))
found LintFindings:src/agent_comms/installer/probes/interpreter.py at src/agent_comms/installer/probes/interpreter.py:3 (I001 [*] Import block is un-sorted or un-formatted)
found LintFindings:src/agent_comms/installer/runtime_stack.py at src/agent_comms/installer/runtime_stack.py:6 (I001 [*] Import block is un-sorted or un-formatted) src/agent_comms/installer/runtime_stack.py:254 (E501 Line too long (104 > 100))
found Unformatted:src/agent_comms/cli_verbs/prepare_runtime.py at src/agent_comms/cli_verbs/prepare_runtime.py:1 (Black would reformat this file)
found Unformatted:src/agent_comms/installer/probes/interpreter.py at src/agent_comms/installer/probes/interpreter.py:1 (Black would reformat this file)
found Unformatted:src/agent_comms/installer/probes/packages.py at src/agent_comms/installer/probes/packages.py:1 (Black would reformat this file)
found Unformatted:src/agent_comms/installer/probes/resolution.py at src/agent_comms/installer/probes/resolution.py:1 (Black would reformat this file)

@trissim
trissim force-pushed the fix/isolated-runtime-inputs branch 2 times, most recently from f50a433 to c12a959 Compare November 1, 2026 09:50
@trissim
trissim force-pushed the fix/isolated-runtime-inputs branch 2 times, most recently from 6ce2cee to 8f587ed Compare November 1, 2026 18:04
@trissim
trissim force-pushed the fix/isolated-runtime-inputs branch 5 times, most recently from 040208e to 46fc678 Compare November 2, 2026 01:33
@trissim
trissim force-pushed the fix/isolated-runtime-inputs branch 6 times, most recently from 168e6cf to e023196 Compare November 2, 2026 15:09
@trissim
trissim enabled auto-merge November 2, 2026 15:29
@trissim
trissim force-pushed the fix/isolated-runtime-inputs branch from e023196 to f8c0d10 Compare November 2, 2026 16:03
@trissim
trissim added this pull request to the merge queue Nov 2, 2026
Merged via the queue into main with commit 0d5afb1 Nov 2, 2026
9 of 10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants