Skip to content

Reuse a cached native bundle only while it matches its archive; pin Seed-OSS ASCII trim - #1572

Merged
leehack merged 2 commits into
mainfrom
sweep/1565-final
Oct 29, 2026
Merged

leehack merged 2 commits into
mainfrom
sweep/1565-final

Conversation

@leehack

@leehack leehack commented Oct 29, 2026 •

Copy link
Copy Markdown
Owner

Summary

Clears two items on tracker #1565:

  • Hook-side defence deferred from #1567 (root cause of #1558): the build hook no longer reuses a .dart_tool/llamadart/native_bundles/<tag>/<bundle>/extracted/ directory whose files are not what the cached archive beside it extracted to. After each extraction it writes extracted.json beside extracted/ (archive SHA-256, size, modification time; every extracted file's relative path and size). Reuse needs that record to match the archive in hand and the directory's files; the archive is re-hashed only when its modification time changed. Otherwise the hook extracts the cached archive again (digest-verified as before) or downloads it if the archive is gone.
  • B12 from the #1569 audit: a test pins the ASCII-only trim in _endsUnopenedSeedOssThought.
Cache state Behavior
Marker matches archive and files Reused, no hashing unless the archive's mtime changed
File replaced/added/removed, or archive replaced Re-extracted from the cached archive (verified), or downloaded
Extraction without its archive Downloaded again
Legacy (no marker), pinned release or cached SHA256SUMS Re-extracted once from the verified cached archive, offline; marker written
Legacy, override cached before the hook kept SHA256SUMS Re-extracted once from the archive in hand, offline, unverified (the same trust the old extraction had); marker written

Design choice: re-extraction instead of native-header validation for legacy caches, because it proves extracted/ equals the archive (headers would accept a real-but-wrong library) and needs no network. File sizes rather than per-file hashes keep reuse cheap; the archive hash is skipped on an unchanged mtime because hashing the 688 MiB CUDA sidecar costs about 4 s at the measured ~180 MB/s.

Production-readiness scope

  • User-facing scope: builds stop bundling libraries that were replaced or added in the hook's llama.cpp cache; existing caches are re-extracted once without network access.
  • Supported platforms/paths: every llama.cpp bundle and backend sidecar the hook downloads (all native targets). llamadart_native_path bundles are unchanged (never reused from extracted/).
  • Unsupported or intentionally unavailable paths: an extracted/ whose archive was deleted is no longer reused offline; the build downloads it again. A same-size in-place edit of a library is not detected (sizes, not hashes).
  • Out of scope / follow-ups: stable-diffusion.cpp and LiteRT-LM caches keep their own completeness checks. Pre-existing network dependency in build_hook_stable_diffusion_integration_test.dart ("the stable_diffusion companion selects and links it in process" downloads a real LiteRT-LM macOS bundle on main too).

Completeness checklist

  • Declared scope is fully implemented, or explicitly reduced above.
  • Unsupported platform/option combinations fail loudly with actionable diagnostics or are clearly documented as unavailable.
  • Public API docs, README/website docs, examples, support matrices, and changelog entries are updated where relevant. (native-build-hooks.md, both changelogs; no API change)
  • Regression coverage covers the original issue plus key negative/version-skew paths where relevant.
  • Public capability changes update the validation coverage registry: N/A, no public capability change.
  • Security/privacy review completed: the marker holds only digests, sizes, mtimes and relative file names.
  • Follow-up work that is useful but not required for this PR is tracked in GitHub Issues, or explicitly marked "None" above.

PR type guidance

  • Bugfix PR: root cause of Hook tests poison the checkout's native bundle cache; next dart test crashes #1558 on the hook side: _acquireBundleDirectory reused any extracted/ holding complete-looking library names, so a text stub there was copied into .dart_tool/lib. Regression tests: build_hook_archive_digest_test.dart group "a cached extraction" (7 tests, all fail on main) and native_extraction_marker_test.dart. Platforms: all.
  • Feature PR: N/A.
  • Docs-only PR: N/A.

Test Plan

  • dart run tool/prepare_workspace.dart
  • dart format --output=none --set-exit-if-changed .
  • dart analyze
  • dart run tool/testing/check_platform_boundaries.dart
  • dart test -p vm -j 1 --exclude-tags local-only (macOS arm64, isolated TMPDIR): +9658 ~126, all passed
  • dart test -p chrome --exclude-tags local-only
  • test/unit/hook twice at default concurrency (isolated TMPDIR each): +555, all passed both times
  • test/unit/hook with outbound HTTP(S) blocked (sandbox-exec): all pass except one test that also needs the network on main (see Out of scope)
  • Failing-first: the 7 new hook tests fail against main's hook/build.dart; the B12 test fails with Unicode trimLeft()
  • Mutation check below

Matrix Evidence

Matrix row Scope covered Platform / model / backend Result Evidence / notes
static-format-analyze format, analyzer, boundaries macOS arm64 PASS local + CI Analyze & Lint
root-vm native-safe unit/integration on the VM macOS arm64 PASS local full suite; CI Linux VM core/runtime/tooling
native-hook-bundles hook cache reuse, legacy caches, offline builds macOS arm64; CI Linux, Windows, macOS PASS local twice; new tests ran in CI Test Linux VM (tooling), Test Native (windows-latest), Test Native (macos-latest) (link test skipped on Windows by design)
root-chrome browser-compatible coverage CI PASS CI Test Web (Chrome); no Web code touched
docs-site website build, links CI PASS CI Docs Build Check
high-risk-exact-head-independent-qa independent blocking review of exact head fresh auditor session, exact head 04c3576 PASS CLEAR: CLEAR at 04c3576, 0 P1/P2; P3s on #1565; evidence /opt/UnitySrc/personal/llama/llamadart-evidence/pr-1572/evidence-1572-04c3576-base-04821e0ab.json
structured-output-adversarial parser/streaming N/A N/A test-only change (B12 pin); no parser code touched
other rows N/A no model, backend, release or bridge surface touched

Mutation check (llamadart-evidence/sweep-1565-final/mut.py, each mutant alone against native_extraction_marker_test.dart + build_hook_archive_digest_test.dart):

Mutant Result Killed by
M1 marker ignored KILLED replaced/added library, legacy rows
M2 marker never written KILLED reused by the next build, legacy rows
M3a legacy override without SUMS rejected KILLED legacy, without a cached SHA256SUMS
M3b legacy cache reused as is KILLED legacy rows
M3c legacy branch writes no marker KILLED legacy, without a cached SHA256SUMS
M3d unverified legacy branch for every legacy cache KILLED legacy whose archive the cached SHA256SUMS does not list
M4 file sizes ignored KILLED replaced library (hook + unit)
M5 extra files ignored KILLED added or removed file
M6 archive digest unchecked on a new mtime KILLED another archive does not match
M7 archive size unchecked KILLED resized archive at the same mtime
M8 archive existence unchecked KILLED without its archive is downloaded again
M9 links ignored KILLED an added link does not match
B12 Unicode trimLeft() in _endsUnopenedSeedOssThought KILLED a public Seed-OSS parse skips only ASCII space before a thought

"Header check accepting anything" does not apply: the design uses no header check.

Review Notes

  • Independent review status: CLEAR at exact head 04c3576 by a fresh auditor session (0 P1, 0 P2).
  • CI status / head SHA: 04c3576, CI all green (35 pass, 5 skipped by selection)

High-risk regression review

  • Classification: high-risk (artifactConsumer)
  • Implementation task: sweep lane for 0.17.0 small follow-ups tracker #1565
  • Independent blocking QA task: fresh auditor session, CLEAR, 0 known PR-caused P1, 0 unresolved threads
  • Exact head / current base: 04c3576 / 176e12e (merge-tree clean)
  • Production-branch deletion, bypass, or miswire proof: mutants M1-M9 above
  • Affected-family real-model/artifact evidence: N/A: no model; hook tests use fake archives through the HTTP fixture
  • Explicit unavailable-family or other N/A evidence: N/A
  • Known PR-caused P1 regressions: 0
  • Unresolved review threads: 0

A Seed-OSS reply that starts with a no-break space before <seed:think>
and ends a thought parses as after a template that opens the thought,
as llama.cpp does; a Unicode trim there (mutant B12 of #1569) now fails.
The build hook writes extracted.json beside each llama.cpp bundle's
extracted/ directory, recording the archive's SHA-256, size and
modification time and every extracted file's size. A later build reuses
extracted/ only while the record matches the cached archive and the
files; otherwise it extracts the archive again or downloads it. A cache
without a record is extracted again once from its cached archive,
offline: verified for the pinned release or a cached SHA256SUMS, as is
for an override cached before the hook kept SHA256SUMS.

Hook tests that seed fake extracted/ dirs now write a matching archive
and marker; without them the hook would download the real bundles.
@leehack leehack mentioned this pull request Oct 29, 2026
29 of 32 tasks
@leehack
leehack marked this pull request as ready for review October 29, 2026 01:30
@leehack
leehack merged commit 0bddcde into main Oct 29, 2026
40 checks passed
@leehack
leehack deleted the sweep/1565-final branch October 29, 2026 01:31
@github-actions

Copy link
Copy Markdown
Contributor

Chat app preview removed for leehack/llamadart-chat-pr-1572.

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