Skip to content

Sync-core hardening: one overlay-sync path, generation-scoped memos, bridge version handshake, patch tooling - #76

Merged
johnsoncodehk merged 4 commits into
masterfrom
cursor/sync-core-hardening-a06b
Sep 26, 2026
Merged

johnsoncodehk merged 4 commits into
masterfrom
cursor/sync-core-hardening-a06b

Conversation

@johnsoncodehk

@johnsoncodehk johnsoncodehk commented Sep 26, 2026 •

Copy link
Copy Markdown
Owner

Follow-up to #75. Four independent changes, one commit each.

chore(tools): stable patch index lines + patch:ts without the tsgo submodule
savePatch pins git diff --abbrev=10, so a shallow clone no longer rewrites every index line of the saved patches. patch:ts no longer needs the typescript-go submodule.

fix(bridge): refuse a bridge.node built from a different package version
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 if 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 an ArenaClient.readHandle error. 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 throws built for typescript-native-bridge (unstamped), this bundle is 6.0.3-bridge.17….

refactor(bridge): one overlay-sync path for every updateSnapshot site

  • planOverlayPush is the only per-file overlay rule. The collect loop, the late extra-extension push and pushHostOverlayToTsgo each had their own copy before.
  • syncSnapshot is the only send: steady params plus a one-shot delta. It replaces the two hand-synced fingerprints _lastUpdateParamsByConfig and _lastOverlayPushKeyByConfig. Both sites now build the same steady params (extraFileExtensions is session-sticky and additionalFiles per-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.
  • Behavior deltas, all at the push site:
    • Files absent on disk now dedupe against the mirror, like everywhere else, instead of being re-sent in full on every query sync.
    • A host==disk file that Go hasn't loaded yet now opens through openFiles (the collect path's behavior) instead of being sent as an overlay.
  • The overlay.sync trace drops its deduped= field: a skipped send carries no content, and only sends with content are traced. triage-overlay-delta-sync is updated to match.

refactor(bridge): snapshot-bound memos live in one generation object
The 18 memos that pushHostOverlayToTsgo cleared by hand now live in newSnapshotCaches(), 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: pass
  • All 85 witnesses pass, both after the overlay-sync commit and on the final tree.
  • check:sim-nav: 1747 diffs, same as the baseline, 0 new.
  • volar npm test: 211 passed.
  • check:sourcefile-guard: pass.
  • Local-only triage-external-edits: estree, tsserver and stablecache pass. tscwatch fails, but it fails identically on the published bridge.17, so this branch didn't cause it (see below).
  • CI: 16/16 green.

Existing bug found along the way (not fixed here)

Plain tsc -w on TNB doesn't pick up content edits to source files. Stock gets them from a FileWatcher on each source file (FileWatcher:: Triggered with a.ts). The thin program never materializes source files under plain tsc -w, so tnbWatchSourceFile never 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 what triage-external-edits' tscwatch phase reports. Tracked separately.

Open in Web Open in Cursor 

cursoragent and others added 4 commits September 26, 2026 03:43
…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
johnsoncodehk marked this pull request as ready for review September 26, 2026 05:17
@johnsoncodehk
johnsoncodehk merged commit 6cd4bb1 into master Sep 26, 2026
16 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