Skip to content

feat(#465 PR-C1): bundle the attested third-party set behind a loader launcher - #527

Merged
raylei50653 merged 33 commits into
mainfrom
feat/465-pr-c1-bundle
Oct 7, 2026
Merged

raylei50653 merged 33 commits into
mainfrom
feat/465-pr-c1-bundle

Conversation

@raylei50653

@raylei50653 raylei50653 commented Oct 4, 2026 •

Copy link
Copy Markdown
Owner

Part of #465 (Phase C PR-C1). This implements owner decision C-D1: the shipping tree now carries the 27 third-party objects of the PR-12 formal run byte-for-byte, and runs without LD_LIBRARY_PATH. The entrypoint and the operator library bytes are both unchanged from PR-12.

Bundles are built and tested locally only. Nothing is distributed until nvJitLink / cuFile / nvshmem redistribution is confirmed (scope §4).

Design (followed the owner's direction: probe --library-path first, preserve bytes)

  • Launcher. bin/saccade_track is a POSIX sh launcher. It runs exec /lib64/ld-linux-x86-64.so.2 --library-path <prefix>/lib/vendor --audit <prefix>/lib/saccade_loader_audit.so <prefix>/libexec/saccade_track "$@".
    • It unsets LD_PRELOAD / LD_AUDIT / LD_LIBRARY_PATH first.
    • --library-path precedes DT_RUNPATH, so the op library's libnvrtc.so.13 resolves from lib/vendor without touching saccade_track.
  • Probe finding (corrects scope doc §5). torch, TensorRT and nvshmem carry DT_RPATH, which the loader searches before --library-path. A copy planted at <prefix>/nvidia/cu13/lib gets loaded silently (probe P4).
    • With the libs at lib/vendor/, every relative RPATH/RUNPATH entry expands inside the prefix. The only exception is libcusparseLt's empty entry (cwd).
  • Secondary fail-closed check. shipping/src/loader_audit.c is an rtld-audit library written in C that needs only libc. It replaces the earlier /proc/self/maps idea and leaves the saccade_track bytes untouched.
    • la_objsearch: for a bundled name, it skips any candidate outside lib/vendor. If such a candidate exists on disk, it exits 127.
    • la_objopen: it checks every mapped object by realpath.
  • Entrypoint pin. Rebuilding the same sources was not byte-identical: three builds gave three sha256 values (nvcc tmpxft names, .rela, build-id). So the tree carries the PR-12 binary (d7c6e0d4…), pinned in shipping/entrypoint_pin.json and installed via SACCADE_SHIPPING_ENTRYPOINT. This is the same model as the op library.
  • Install. shipping/third_party_set.json pins each object by SONAME, sha256, source wheel and license files. The install copies and hash-checks every object into lib/vendor/, and puts the license files under licenses/, plus THIRD_PARTY.md.
  • Tools. check_shipping_bundle.py (static / sources / runtime), export_third_party_set.py, and bundle / bundle-strace modes for run_shipping_container.sh. There are 21 unit tests, including the auditor on a real loader.

Acceptance criterion redefined (needs owner review)

G2-2 changes from "exactly one execve" to an exec chain of exactly two: the launcher, then /lib64/ld-linux-x86-64.so.2 with the launcher's arguments. Neither one is Python (docs §17.4 gate 5).

Formal run: r2 at 16233e92, PASS (docs §17.5)

The contract was committed in 51840396, before any measurement; amendment A1 is in 16233e92.

  • Gates 1–2: install with all pins checked; 11/11 static checks pass.
  • Gate 3, host via the launcher: EXACT (detector 5316/5316, MOT txt 7/7, graph captures 7/7). Byte-identical to the PR-12 formal run. sources: every third-party object loaded from tree/lib/vendor.
  • Gate 4, clean ubuntu:24.04 with LD_LIBRARY_PATH unset: EXACT, identical to gate 3.
  • Gate 5, strace: exec chain launcher → loader; no Python / Triton opens; the opened set equals the bundle. EXACT.
  • Negative controls N1–N9: all caught.
    • N4 (planted libcublas): exit 127 from the auditor.
    • N5 (same, without --audit): the foreign copy is loaded and the runtime check fails. This shows it is the auditor that blocks N4.
  • r1 (51840396) superseded by A1. Gates 1–5 also held in r1, but two negative controls did not run as written:
    • N3: the static checker crashed on a missing vendor file. Fixed, with a test.
    • N6: my prediction was wrong. The hostile LD_PRELOAD hit the launcher's own sh, which then exited 127. N6 is now split into N6a and N6b. The whole run was repeated.

Named limits (§17.6):

  • The launcher's own sh is not protected from the caller's LD_PRELOAD (N6b observation). The entrypoint process is protected.
  • The auditor checks paths, not bytes. Byte integrity comes from the install-time check and the static check, and later from the PR-C3 MANIFEST.
  • The pinned entrypoint file lives in the PR-12 results directory, which is not under version control.
  • Still sm_120 only, one WSL2 host, about 3.7 GiB, non-atomic install. The parity harness still passes --measurement-mutation (PR-C2).

Stack merged in (10-07)

#528 (PR-C1 republish) merged into this branch; it carries #529 (PR-C2 shipping CLI, docs §18) and #530 (PR-C2 republish). Main-base CI at b73d0a65: all checks pass, including pytest.

Review fixes at b73d0a65 (docs §18.10–§18.11)

  • [P1] Fail-open launcher, amendment A2. The loader ignores an --audit library it cannot load. With the auditor missing, truncated or not an auditor, the old launcher ran the entrypoint unprotected: a planted DT_RPATH copy loaded and the process exited 0. Fix in 71acc415:
    • The launcher first runs the same loader, library path and auditor on /bin/sh -c : with SACCADE_AUDIT_PROBE=1.
    • After deriving <prefix>, the auditor's la_version prints a ready line and exits.
    • If the launcher does not read that line, it exits 127. The caller's SACCADE_AUDIT_PROBE is unset.
    • G2-2 becomes three execs: launcher → loader in one process, and the probe in a child. This redefinition needs owner review.
  • [P2] runtime ignored alias targets. Both runtime gates now also check the strace -yy returned-fd target (0f26d08a).
  • [P2] rejected hard-coded the model root. no_model_root_open now also covers the run's own --model-root / --config / --lineage / --attestation. Relative values are resolved against the evidenced cwd; if none is evidenced, the check fails closed (0f26d08a).
    • A clean replay of the 13 existing C1/C2 reports at 0f26d08a gives identical per-check outcomes (results/465_prc1_bundle/review_fix_0f26d08a/).
  • Tests: real-loader tests cover a missing, truncated, empty and non-auditor library: each exits 127 and nothing runs. With the old launcher, all four ran the planted copy. They also cover a caller-set probe variable, plus exec-chain negatives and the P2 regressions (117 tests pass in the two shipping test files).
  • A2 formal run at 036d6b95 (contract §18.10 committed before measurement): PASS. It reran the whole §18.4 run (gates 1–6, M1–M6, N1–N9) on the C1+C2 head.
    • Gates 3–5 are EXACT: detector 5316/5316, MOT txt 7/7, graph 7/7, byte-identical to the PR-12 formal run.
    • The 3-exec chain passes.
    • Rejection 3×5 passes; the 7 mutation controls are caught.
    • New controls: N10–N12 (auditor missing / half / libcudart copy, with the planted copy present) each exit 127 with only launcher + probe exec'd and no output. N13 (caller SACCADE_AUDIT_PROBE=1) exits 0 with identical MOT17-05 output.
    • N5 now uses the PR-C1 launcher without --audit; the planted copy loads and the runtime gates fail, as before.
    • Results: results/465_prc2_cli/full_036d6b95/.
  • Limits: probe and exec are two loader starts, so this makes no race claim; anyone who can rewrite the tree can rewrite the launcher too. The auditor's bytes are still not verified at run time (PR-C3 MANIFEST).
  • Republish: stacked chore(provenance): republish the runtime coordinate for #465 PR-C1 A2 #531 (implementation e00a504c → 568c0e08; only the launcher and the auditor changed). pre_push on the combined head bc01144a: exit 0, 5212 passed. CI on this branch alone will fail the coordinate tests until chore(provenance): republish the runtime coordinate for #465 PR-C1 A2 #531 is merged.

Review fixes at 93f4de43 — amendment A3 (docs §18.12–§18.13)

After #531 merged (93f4de43), main-base CI passed all 8 checks. The review found three P2 coverage gaps. None of them was observed as a parity violation in a shipping run.

  • Auditor alias bypass. la_objopen classified an object by its requested basename before resolving it, so payload → foreign libfoo.so ran the foreign code. It now resolves with realpath first and classifies by both the mapped name and the real name (f1d98b93). A real-loader CPU test covers it: the direct foreign copy exits 127, and the alias now exits 127 too (the old auditor printed the foreign result).
  • runtime passed with unresolved opens. Unresolved records now fail the Python-open and opened-set gates.
  • No -yy in the evidence. bundle-strace now records with -yy.
    • runtime and rejected require a returned-fd target on every successful open. --legacy-plain-trace evaluates historical plain logs and records that alias targets were not checked.
    • fd targets are classified by SONAME family (libstdc++.so.6.0.33 → libstdc++.so.6, 06002566). The dev trial needed this: without it, two base-system targets were reported as foreign.
  • A3 formal run at 276659a8 (contract committed first): PASS. Gates 1–6, M1–M6 and N1–N13 give the same results as the A2 run.
    • The -yy container trace has 6,533 opens; all 6,028 successful ones carry an fd target, and 0 are unresolved.
    • New N14: the plain A2 trace fails without --legacy-plain-trace (6,028 unresolved) and passes with it.
    • Results: results/465_prc2_cli/full_276659a8/.
  • Limit: classification is still by name (real basename, SONAME family). A renamed foreign regular file reached through a non-bundled NEEDED or dlopen is not recognized; byte integrity stays with the install-time sha256, static and the PR-C3 MANIFEST.
  • Republish: stacked chore(provenance): republish the runtime coordinate for #465 PR-C1 A3 #532, merged into this branch (ff7359d4) after review. Implementation 568c0e08 → 97943682; only loader_audit.c changed. Main-base CI at ff7359d4: all 8 checks pass.

Review fixes at ff7359d4 — amendment A4 (docs §18.14–§18.15)

The review at ff7359d4 found four P2 gaps and one P3. As before, none of them was observed as a parity violation in a shipping run. Fix e6b57ac8.

  • Auditor: versioned alias. payload → libcudart.so.13.1.0 matched neither the bundled SONAME libcudart.so.13 nor the real name, so it was allowed. la_objopen now compares names by SONAME family (the checker's _object_class rule). CPU real-loader test: aliases to libfoo.so.1.0.0 and libfoo.so.13 exit 127; an alias to another family still runs.
  • Exec chain: whole loader argv. The checker used to compare only the first four loader arguments and test whether the entrypoint appeared anywhere. The loader argv must now equal exactly: loader options, --argv0 <launcher argv[0]>, the entrypoint in the program slot, then the launcher's own arguments.
  • Incomplete exec records fail closed. An execve/execveat line that strace did not record to completion is kept as a failed exec, so the chain fails.
  • Default model root. rejected simulates the entrypoint's argv parse (track_driver.hpp). When --model-root is not consumed, every evidenced cwd is protected; without cwd evidence the check is unresolved and fails. _within("/") now covers every path.
  • Launcher (P3): the prefix must not contain ; either.
  • A4 formal run at 1ae402c2 (contract committed first): PASS. Gates 1–6, M1–M6 and N1–N14 give the same results as A3.
    • The -yy trace has 6,485 opens; all 5,992 successful ones carry an fd target, and 0 are unresolved.

    • New controls, each also evaluated with the A3 checker as a reproduction record:

      Control A4 A3
      N15: /bin/true in the program slot exec chain FAIL PASS
      N16: unfinished Python execve exec chain FAIL PASS
      N17a: --model-root removed no_model_root_open FAIL PASS
      N17b: cwd /work + engine open no_model_root_open FAIL, attempted = the engine PASS
      N18: tree at /opt/sac;cade launcher exit 2 loader exit 127
    • N15–N17 are synthetic: one edit each to a copy of a real trace from this run.

    • Results: results/465_prc2_cli/full_1ae402c2/.

  • Limits: the SONAME family is still a name, so a renamed foreign file outside any bundled family is not recognized. The versioned-alias control is CPU-only, because doing it on the shipping tree needs a modified pinned ELF. The default-root check depends on mirroring the entrypoint's parse rules.
  • Republish: stacked chore(provenance): republish the runtime coordinate for #465 PR-C1 A4 #533 (implementation 97943682 → 7d4dc790; loader_audit.c and the launcher changed). pre_push on the combined head 1c1fe269: exit 0, 5241 passed. CI on this branch alone fails the coordinate tests until chore(provenance): republish the runtime coordinate for #465 PR-C1 A4 #533 is merged.

Scope doc

native_runtime_phase_c_scope.md gets a correction note: DT_RPATH, the launcher plus auditor design, and the entrypoint pin. It also records C-D5 = minisign (v1).

Checks

🤖 Generated with Claude Code

raylei50653 and others added 4 commits October 4, 2026 21:13
… launcher

Phase C PR-C1 (owner decision C-D1): the shipping tree carries the 27
third-party objects of the PR-12 formal run byte for byte at lib/vendor/,
pinned by sha256 in shipping/third_party_set.json, and runs without
LD_LIBRARY_PATH.

- bin/saccade_track is a POSIX sh launcher: it execs the system loader
  with --library-path <prefix>/lib/vendor --audit <auditor> on
  libexec/saccade_track. The entrypoint is the PR-12 binary (pinned in
  shipping/entrypoint_pin.json; a rebuild of the same sources was observed
  not to be byte-identical) and the operator library is unchanged.
- shipping/src/loader_audit.c: an rtld-audit library, the secondary
  fail-closed provenance check. Torch, TensorRT and nvshmem carry DT_RPATH
  entries that the loader searches before --library-path; for a bundled
  name, a candidate outside lib/vendor that exists makes the process exit
  127, and a mapped bundled object must come from lib/vendor.
- install: third-party objects and each wheel's license files are copied
  from the pinned roots with sha256 checks; licenses/ + THIRD_PARTY.md.
- scripts/native/check_shipping_bundle.py (static / sources / runtime),
  export_third_party_set.py, run_shipping_container.sh bundle modes, and
  tests, including the auditor on a real loader.
- docs §17: the loader probe, the change, and the measurement contract for
  the formal run (gates 1-5, N1-N9), committed before the run. The Phase C
  scope doc §5 is corrected (DT_RPATH, launcher + auditor) and records
  C-D5 = minisign.

Local build and test only; nothing is distributed before the nvJitLink /
cuFile / nvshmem redistribution question is confirmed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ts; N6 split

The first formal run (r1, 5184039) held gates 1-5 but two negative
controls did not run as written: N3's static check errored (the closure ran
readelf on the missing vendor object) and N6's prediction failed (the
container LD_PRELOAD reached the launcher's own sh, whose loader exited 127
on the preloaded libcublas's missing libcublasLt; saccade_track never
started). The closure now reports a missing vendor object (with a test);
N6 becomes N6a (hostile LD_LIBRARY_PATH) and N6b (+ LD_PRELOAD of an
object the sh can load). The whole run is repeated at this commit (r2).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…-N9)

r2 (contract §17.4 incl. A1): EXACT on the host through the launcher, in
the clean container without LD_LIBRARY_PATH and under strace (detector
5316/5316, MOT txt 7/7, graph captures 7/7), byte-identical to the PR-12
formal run; exec chain launcher -> loader; opened set = the bundle. All
negative controls caught. Limits: the launcher's own sh is not protected
from LD_PRELOAD; the auditor checks paths, not bytes; the entrypoint bytes
come from the PR-12 results directory (the build is not reproducible).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Archive the outgoing canonical (implementation 769928a8cff9daa9, the PR-12
publication) and promote a fresh controlled-host capture (build/runtime_identity,
Release, --run-probe --require-complete) at the PR-C1 head 6f1b5a8.

Axes:
* implementation MOVED 769928a8cff9daa9 -> 983b89fc660ac8ed; files 277 -> 282.
  Added (5): shipping/cmake/install_third_party.cmake (bundle install step),
  shipping/entrypoint_pin.json (pinned PR-12 entrypoint bytes),
  shipping/launcher/saccade_track.sh (the loader launcher),
  shipping/src/loader_audit.c (rtld-audit provenance check),
  shipping/third_party_set.json (the pinned third-party set).
  Changed (1): shipping/CMakeLists.txt (install layout, auditor target,
  entrypoint pin, third-party install). Removed: none.
* environment, decision_surface, identity_semantics, runtime_inputs: unchanged.
* probe: re-run fresh (not reused); behavior 2dabed0b, equal to the PR-12
  publication. Probe equality is not an equivalence claim; equivalence stays
  unproven.

Verified: check_runtime_identity_staleness.py --mode attested exit 0. The
attested operator library build/libsaccade_scan_torchop.so is unchanged
(aa84cccd) after the capture build.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
raylei50653 and others added 6 commits October 4, 2026 22:56
… hooks behind a variant

The shipping saccade_track now accepts only its interface (--config,
--lineage, --attestation, --model-root, --out, --report, --trace,
sequences); --measurement-mutation, --schedule serial and --max-frames
are refused as unknown arguments before any file is read. They move to
saccade_track_measurement, a developer build that is not installed.

The mutation enums, the *_for_measurement setters and their branches are
compiled only into the _measurement variant of the four runtime
libraries (SACCADE_SHIPPING_MEASUREMENT_HOOKS); the shipping objects do
not declare them. saccade_track's POST_BUILD and check_shipping_bundle.py
static refuse an entrypoint that carries any string of
shipping/measurement_surface.json; `rejected` judges a launcher run given
a removed option (exit 2, no model-root / operator-library / GPU device
open, no output). The parity harness runs the shipping binary with its
interface only and the negative controls with --entrypoint measurement;
--against also compares the graph counts.

No stage computation, engine, operator library, third-party set,
launcher or auditor changes. docs §18.1-18.3; the contract and the new
entrypoint pin follow in their own commit.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Freezes the PR-C2 formal run before any measurement: gates 1-5 as in
§17.4 (detector 5316/5316, MOT 7/7, graph captures 7/7, against the
PR-12 formal run incl. graph counts), gate 6 for the CLI surface
(removed options refused in the clean container before any model-root,
operator-library or GPU device open; the developer build with mutation
none equals shipping 7/7; serial reference; the six mutations and
ref_edit caught), negative controls M1-M6 for the new checks, and the
§17.4 N1-N9 rerun with the new pin.

shipping/entrypoint_pin.json now names saccade_track built at 04f6f13
(clean tree, fresh build-prc2-pin/, installed with RUNPATH
$ORIGIN/../lib): sha256 92f74ef4..., 8736640 bytes. Comment-only updates
in shipping/CMakeLists.txt and the checker's docstring; build-prc2-pin/
is ignored.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…, N1-N9)

Formal run results/465_prc2_cli/full_e63fde3f (clean tree, gpu0 lease):
the pinned PR-C2 entrypoint 92f74ef4 is EXACT on the host, in the clean
container and under strace (detector 5316/5316, MOT 7/7, graph captures
7/7), identical to the PR-12 formal run in txt, trace and graph counts.
The removed options are refused before any model-root, operator-library
or GPU device open; the developer build with mutation none equals
shipping 7/7; the serial reference is EXACT; all six mutations and
ref_edit are caught. M1-M6 and the §17.4 N1-N9 rerun are all caught.
Operator library aa84cccd and the pin unchanged before and after.

§18.6 limits, §18.7 reproduction.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Archive the outgoing canonical (implementation 983b89fc660ac8ed, the PR-C1
publication) and promote a fresh controlled-host capture (build/runtime_identity,
Release, --run-probe --require-complete) at the PR-C2 head 60d66da.

Axes:
* implementation MOVED 983b89fc660ac8ed -> e00a504ca78857e4; files 282 -> 286.
  Added (4): shipping/cmake/check_no_measurement_surface.cmake,
  shipping/measurement_surface.json, shipping/tools/saccade_track_measurement.cpp,
  shipping/tools/track_driver.hpp (CLI split and measurement boundary).
  Changed (13): shipping/CMakeLists.txt, shipping/entrypoint_pin.json, the five
  hook headers and five runtime sources (hooks behind
  SACCADE_SHIPPING_MEASUREMENT_HOOKS), shipping/tools/saccade_track.cpp.
  Removed: none.
* environment, decision_surface, identity_semantics, runtime_inputs: unchanged.
* probe: re-run fresh (not reused); behavior 2dabed0b, equal to the PR-C1
  publication. Probe equality is not an equivalence claim; equivalence stays
  unproven.

Verified: check_runtime_identity_staleness.py --mode attested exit 0. The
attested operator library build/libsaccade_scan_torchop.so is unchanged
(aa84cccd) after the capture build.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
raylei50653 and others added 11 commits October 7, 2026 10:24
chore(provenance): republish runtime coordinate for #465 PR-C2
…ction checks

`rejected` classified only the requested pathname, so a successful open
through a symlink or device alias could pass while `strace -yy` showed the
opened object inside the model root, a GPU device, or an output path. It
now checks the returned-fd target as well. An annotated record that
succeeded without a target fails closed.

Relative `--out`/`--trace`/`--report` values stayed relative while opens
were compared as absolute paths. They are now resolved against every cwd
evidenced by `AT_FDCWD` annotations. When no cwd is evidenced, `no_output`
fails closed and lists the value in `unresolved_outputs`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…hecker fixes

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
feat(#465 PR-C2): isolate measurement hooks from shipping CLI
chore(provenance): republish the runtime coordinate for #465 PR-C1
…nputs from argv

`runtime` inspected only the requested path. A successful open through an
alias whose target was a Python library or a stray copy passed both the
Python-open and opened-set gates. Both gates now check the `strace -yy`
returned-fd target as well. A target inside the mount that is missing from
the inspected tree is reported as a foreign open instead of crashing the
check.

`rejected` checked only the default mounted model root. `no_model_root_open`
now also covers the run's own `--model-root`, `--config`, `--lineage` and
`--attestation` values. Relative values are resolved against evidenced cwds
the same way output arguments are. A value without a cwd fails closed and
is listed in `unresolved_inputs`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The loader ignores an `--audit` library it cannot load ("cannot be loaded
as audit interface ... ignored"). A missing, truncated or non-auditor
`saccade_loader_audit.so` let the entrypoint run without provenance
enforcement, so a planted DT_RPATH copy loaded and the process exited 0.

The launcher now first runs the same loader with the same library path
and auditor on `/bin/sh -c :`, with SACCADE_AUDIT_PROBE=1. Once the
auditor's la_version has derived <prefix>, it writes a ready line and
exits before the program runs. If the launcher does not read that line,
it exits 127. The caller's SACCADE_AUDIT_PROBE is unset, so it cannot
reach the entrypoint's loader.

The G2-2 exec chain becomes three execs. The launcher, then the loader,
run in one process; the probe runs in a child process with its exact argv.
strace -ff logs are grouped per process. Real-loader tests cover a missing,
truncated, empty and non-auditor library (exit 127, nothing run) and a
caller-set probe variable.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… initialization

Records the fail-open finding, the probe design and the dev observations.
Amends the formal-run contract before measurement: three-exec chain,
validity diff excluding loader_audit.c, M1 adds launcher_exact, N5 uses the
PR-C1 launcher without --audit, new N10-N13.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…1-M6, N1-N13)

Also adds a §17.8 pointer for the "§17.8, A2" references in the launcher
and auditor comments. The amendment itself is in §18.10; the measured
bytes are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…0f26d08

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Archive the outgoing canonical (implementation e00a504ca78857e4, the PR-C2
publication) and promote a fresh controlled-host capture (build/runtime_identity,
Release, --run-probe --require-complete) at the A2 head fc1b74f.

Axes:
* implementation MOVED e00a504ca78857e4 -> 568c0e0873dfbaeb; files 286 -> 286.
  Changed (2): shipping/launcher/saccade_track.sh (auditor readiness probe),
  shipping/src/loader_audit.c (la_version answers the probe). Added: none.
  Removed: none.
* environment, decision_surface, identity_semantics, runtime_inputs: unchanged.
* probe: re-run fresh (not reused); behavior 2dabed0b, equal to the PR-C2
  publication. Probe equality is not an equivalence claim; equivalence stays
  unproven.

Verified: check_runtime_identity_staleness.py --mode attested exit 0. The
attested operator library build/libsaccade_scan_torchop.so is unchanged
(aa84cccd) after the capture build.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
raylei50653 and others added 6 commits October 7, 2026 11:46
chore(provenance): republish the runtime coordinate for #465 PR-C1 A2
… -yy targets

Three review findings at 93f4de4:

- The auditor classified a mapped object by its requested name before
  resolving it. A symlink alias (payload -> a foreign libfoo.so) passed
  la_objopen and the foreign code ran. la_objopen now resolves first and
  classifies by both the mapped name and the real name. Only an object
  neither check applies to (the vDSO) may stay unresolved.
- `runtime` reported PASS with unresolved open records. Unresolved records
  now block the Python-open and opened-set gates.
- bundle-strace recorded without -yy, so alias targets were never
  available in the evidence. It now records with -yy. `runtime` and
  `rejected` treat a successful open without a returned-fd target as
  unresolved. `--legacy-plain-trace` evaluates a historical plain log and
  the report says so. A non-path target (pipe:[N]) counts as named.

Real-loader test: the direct foreign libfoo.so exits 127. Through the
`payload` alias, the old auditor printed the foreign result; the new one
exits 127.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
With -yy, a base-system SONAME symlink is annotated with its versioned
file (libstdc++.so.6 -> libstdc++.so.6.0.33, libz.so.1 -> libz.so.1.3).
classify_name knows only SONAMEs, so the dev trial reported both as
foreign. Trailing version components are now dropped until a name
classifies. As before, this is a name check, not a byte check. An alias
named like a base-system library that points at a third-party object is
still foreign.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ce, unresolved fail closed

Contract before measurement: the A2 run is repeated at the A3 commit with
-yy traces and fd targets required, and N14 is added (plain A2 evidence
fails without --legacy-plain-trace).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…1-M6, N1-N14)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Archive the outgoing canonical (implementation 568c0e0873dfbaeb, the A2
publication) and promote a fresh controlled-host capture (build/runtime_identity,
Release, --run-probe --require-complete) at the A3 head a1506cf.

Axes:
* implementation MOVED 568c0e0873dfbaeb -> 9794368288ee3fe9; files 286 -> 286.
  Changed (1): shipping/src/loader_audit.c (la_objopen classifies by real
  path). Added: none. Removed: none.
* environment, decision_surface, identity_semantics, runtime_inputs: unchanged.
* probe: re-run fresh (not reused); behavior 2dabed0b, equal to the A2
  publication. Probe equality is not an equivalence claim; equivalence stays
  unproven.

Verified: check_runtime_identity_staleness.py --mode attested exit 0. The
attested operator library build/libsaccade_scan_torchop.so is unchanged
(aa84cccd) after the capture build.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
raylei50653 and others added 5 commits October 7, 2026 16:27
chore(provenance): republish the runtime coordinate for #465 PR-C1 A3
… execs, the default model root

Review of #527 at ff7359d (A4):

- auditor: la_objopen classifies the mapped and real names by SONAME
  family, so payload -> libcudart.so.13.1.0 is in the bundled family
  libcudart.so.13 and must come from lib/vendor.
- launcher: the prefix must not contain ';' either; the loader splits
  --library-path on both delimiters whatever the quoting.
- check_shipping_bundle exec chain: the loader argv must be exactly the
  loader options, --argv0 <launcher argv[0]>, the entrypoint in the
  program slot and the launcher's own arguments.
- strace_records: an exec that strace did not record to completion is
  kept as a failed exec, so the chain fails.
- rejected: the entrypoint's default model root (its cwd) is protected
  when its parse sets no --model-root; with no evidenced cwd it is
  unresolved. _within("/") now covers every path.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…er argv, incomplete execs, default model root

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…1-M6, N1-N18)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Archive the outgoing canonical (implementation 9794368288ee3fe9, the A3
publication) and promote a fresh controlled-host capture (build/runtime_identity,
Release, --run-probe --require-complete) at the A4 head f69577f.

Axes:
* implementation MOVED 9794368288ee3fe9 -> 7d4dc7907dbef1aa; files 286 -> 286.
  Changed (2): shipping/src/loader_audit.c (la_objopen classifies by SONAME
  family), shipping/launcher/saccade_track.sh (the prefix must not contain
  ';'). Added: none. Removed: none.
* environment, decision_surface, identity_semantics, runtime_inputs: unchanged.
* probe: re-run fresh (not reused); behavior 2dabed0b, equal to the A3
  publication. Probe equality is not an equivalence claim; equivalence stays
  unproven.

Verified: check_runtime_identity_staleness.py --mode attested exit 0. The
attested operator library build/libsaccade_scan_torchop.so is unchanged
(aa84cccd) after the capture build.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
chore(provenance): republish the runtime coordinate for #465 PR-C1 A4
@raylei50653
raylei50653 merged commit aca28d1 into main Oct 7, 2026
8 checks passed
@raylei50653
raylei50653 deleted the feat/465-pr-c1-bundle branch October 8, 2026 08:22
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.

1 participant