Sync-core hardening: one overlay-sync path, generation-scoped memos, bridge version handshake, patch tooling - #76
Merged
Conversation
…h through savePatch git's default --abbrev scales with the clone's object count, so saving from a shallow submodule rewrote every index line (the committed tsgo patches carried 9-char hashes, the TypeScript ones 10). savePatch now passes --abbrev=10 and takes pathspecs, so the five hand-rolled diff-and-write blocks in the save scripts are gone; the tsgo patches take a one-time index-line-only rewrite. patch-typescript no longer syncs vendor/native-preview: applying the TypeScript delta does not read it, build:js already syncs it, and the coupling made patch:ts fail without the typescript-go submodule. Co-authored-by: Johnson Chu <johnsoncodehk@users.noreply.github.com>
build-bridge.js stamps the package.json version into the binary (-ldflags -X main.bridgeVersion); the shim exports it as `version` and the loader throws before setLibPath when it differs from the bundle's own package.json. A stale platform package in a pnpm store paired with a newer bundle previously surfaced as an ArenaClient.readHandle error far from the cause. Co-authored-by: Johnson Chu <johnsoncodehk@users.noreply.github.com>
ensureProject, its late extra-extension push and pushHostOverlayToTsgo each re-implemented the per-file overlay decision and the send/commit/dedupe bookkeeping, with two fingerprints (_lastUpdateParamsByConfig for the rebuild dedupe, _lastOverlayPushKeyByConfig for the query fast path) that had to be kept in step by hand. planOverlayPush is now the only per-file rule (diverging text -> mirror skip / edit delta / full content; text back at disk -> one re-push, then forget), and syncSnapshot the only send: steady params (options, open set, sticky extras and additional roots) plus a one-shot delta, skipped against the last landed steady params when the delta is empty. Both sites now build the same steady params, so a rebuild and the following query sync compare equal by construction. The push walk drops its hostOnly/inTsgo special cases from before the openFiles channel existed: files absent on disk dedupe against the mirror like everywhere else, and a host==disk file not yet in Go's program is opened through openFiles instead of being re-sent as an overlay. Co-authored-by: Johnson Chu <johnsoncodehk@users.noreply.github.com>
… object pushHostOverlayToTsgo reset 18 snapshot-bound memos through a hand-kept clear list, and a new memo had to remember to join it. They are now fields of newSnapshotCaches(), and a snapshot bump replaces the whole object; the per-file scan caches that deliberately reuse across generations stay outside. Co-authored-by: Johnson Chu <johnsoncodehk@users.noreply.github.com>
johnsoncodehk
marked this pull request as ready for review
September 26, 2026 05:17
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Follow-up to #75. Four independent changes, one commit each.
chore(tools): stable patch index lines + patch:ts without the tsgo submodule
savePatchpinsgit diff --abbrev=10, so a shallow clone no longer rewrites everyindexline of the saved patches.patch:tsno longer needs the typescript-go submodule.fix(bridge): refuse a bridge.node built from a different package version
build-bridge.jsstamps the package.json version into the binary (-ldflags -X main.bridgeVersion). The shim exports it asversion, and the loader throws beforesetLibPathif it doesn't match the bundle's own package.json. This is the same pnpm-store situation hit during #75: a stale platform package paired with a newer bundle used to fail far away as anArenaClient.readHandleerror. It now fails at load with the bridge path, both versions, and the fix. README troubleshooting has a row for it. Checked both ways: the stamped bridge runs, and swapping in the published (unstamped) bridge.17 throwsbuilt for typescript-native-bridge (unstamped), this bundle is 6.0.3-bridge.17….refactor(bridge): one overlay-sync path for every updateSnapshot site
planOverlayPushis the only per-file overlay rule. The collect loop, the late extra-extension push andpushHostOverlayToTsgoeach had their own copy before.syncSnapshotis the only send: steady params plus a one-shot delta. It replaces the two hand-synced fingerprints_lastUpdateParamsByConfigand_lastOverlayPushKeyByConfig. Both sites now build the same steady params (extraFileExtensionsis session-sticky andadditionalFilesper-config sticky on the Go side, and Go re-opens only files it doesn't already hold), so a rebuild and the query sync right after it compare equal by construction.openFiles(the collect path's behavior) instead of being sent as an overlay.overlay.synctrace drops itsdeduped=field: a skipped send carries no content, and only sends with content are traced.triage-overlay-delta-syncis updated to match.refactor(bridge): snapshot-bound memos live in one generation object
The 18 memos that
pushHostOverlayToTsgocleared by hand now live innewSnapshotCaches(), and a snapshot bump replaces the whole object. The per-file scan caches stay outside, since they are reused across generations on purpose.Verification (local, final tree)
check:lib,check:enums,check:go-as-guards, README ledger,ci-witness-groups all: passcheck:sim-nav: 1747 diffs, same as the baseline, 0 new.npm test: 211 passed.check:sourcefile-guard: pass.triage-external-edits:estree,tsserverandstablecachepass.tscwatchfails, but it fails identically on the published bridge.17, so this branch didn't cause it (see below).Existing bug found along the way (not fixed here)
Plain
tsc -won TNB doesn't pick up content edits to source files. Stock gets them from aFileWatcheron each source file (FileWatcher:: Triggered with a.ts). The thin program never materializes source files under plaintsc -w, sotnbWatchSourceFilenever registers any watchers, and the wildcard directory watcher doesn't fire on content changes. It reproduces on the published bridge.17, and it is exactly whattriage-external-edits'tscwatchphase reports. Tracked separately.