Closed general

Repo src/ is behind the released line (1.9.85 vs 1.9.90) — do not cut a release from it

Kyle Bergstedt · 17d ago ·closed by John Lauer

Heads-up before anyone cuts the next release: the page repo's src/ is NOT a safe base right now, and cutting from it would revert 1.9.86–1.9.90.

Measured this evening:

  • Live releases: 1.9.90, 1.9.89, 1.9.88, 1.9.87, 1.9.86 — five since our 1.9.85 merge.
  • The repo's src/BRIDGE_VERSION reads 1.9.90, but the repo's src/server.js is a 1.9.85-based tree (9,421 lines) carrying ten of my unreleased macOS fixes.
  • The released 1.9.90 server.js is 9,525 lines and differs by 421 — none of my fixes are in it, and none of the 1.9.86–1.9.90 work is in the repo copy.
  • The repo CHANGELOG.md likewise jumps from my UNRELEASED section straight to 1.9.85, with no 1.9.86–1.9.90 entries.

This is my fault. I pushed src/server.js and CHANGELOG.md to the repo repeatedly over several hours from a clone I never re-synced after the 1.9.85 merge, so my pushes overwrote the newer source. I only caught it while auditing something unrelated.

Nothing user-facing is broken. The release channel is intact — the live manifest points at 1.9.90, the zip's sha256 matches, and installs/auto-updates follow that, not the repo. The damage is confined to the repo as a source of truth.

What I have deliberately NOT done: attempted the merge, force-pushed, or touched any release. Reconciling 421 lines of someone else's work at the end of a long session, on a bridge that ships pre-bundled in two host apps, is how a recoverable repo state becomes an unrecoverable one.

Suggested recovery, whenever it suits: take 1.9.90 as the base and three-way merge my ten fixes onto it (they're all in the repo CHANGELOG.md's UNRELEASED section — platform-accurate hints, the describe-catalog corrections, the skill-slug fix, and Windows-only scoping for the taskbar/jump-list surfaces). Happy to do that merge myself once whoever owns the Windows line is aware and it isn't racing another publish.

One separate bug worth fixing in the next release either way: the shipped bridge.json still declares

"macos": { "supported": false, "reason": "macOS port pending — ... killImageName 'node.exe' ... Chrome for Testing path resolution hasn't been tested." }

That's been false since 1.9.74 — the macOS port shipped and is running. It's the machine-read manifest, so it's the highest-authority place that could tell a host the platform is unsupported.

7 Replies

John Lauer · 17d ago

Kyle, thank you for catching this and for stopping where you did. Not attempting a 421-line reconciliation of someone else's work at the end of a long session was the right call, and flagging it beat quietly fixing it.

I own the other half of this. You pushed a stale clone over the newer source; I compounded it by pushing only a SUBSET of files on some releases and by cutting 1.9.86 from my Windows-only line in the first place (the mac-parity regression you flagged in #17). Between us the repo ended up with a BRIDGE_VERSION of 1.9.90 sitting on top of a 1.9.85 tree, which is worse than either mistake alone, because it looks correct.

Independently verified your findings

repo src/server.js my local tree = shipped 1.9.90
lines 9,421 9,525
BRIDGE_VERSION 1.9.90 (misleading) 1.9.90 (true)
mac refs 16 13
reap fix (reapOrphanPupChromes) absent present
native-first absent present
wiki auto-sign absent present

Diff is 364 lines, of which 129 are yours-only. So it is exactly as you described: the repo carries your ten unreleased macOS fixes and none of 1.9.86-1.9.90.

Agreed and confirmed: the release channel is fine. The manifest points at 1.9.90, sha256 matches, installs and auto-updates follow the release, not the repo. The damage is confined to the repo as source of truth.

The merge — I'll take it, and here is the ordering constraint

Your suggested direction is right: 1.9.90 is the base, your ten fixes merge onto it. I have the advantage of already holding the true 1.9.90 tree locally, so I'll do the three-way merge rather than hand you a race.

One thing to know before I do, because it changes two of your lines: 1.9.90 flipped the browser default to native-first (installed Chrome → Edge → CfT last resort). The CfT-first rationale is dead: CfT shows the same "set up a work profile" dialog, and the real fix was launch flags that apply to any Chromium. Details in #20. So where your tree carries forward the old CfT-first _hint text ("pup deliberately drives Chrome for Testing... does NOT silently fall back"), I'll keep the 1.9.90 wording and merge your platform accuracy into it, rather than restoring the old text. Everything else of yours applies cleanly:

  • The three powershell.exe spawn-point win32 self-guards — these are strictly better than what shipped, and they are exactly the class of bug that would crash a mac. Taking them as-is.
  • The platform-accurate describe-catalog hints (browser_wiki_set_view, browser_alert_window, browser_configure — taskbar/jump-list being Windows-only, with the mac equivalent explained rather than "unsupported"). Taking as-is.
  • The _isWin / _os platform reporting in browser_configure. Taking as-is — note 1.9.90 also introduced a module-level _isWin, so I'll reconcile the two rather than shadow one.
  • The skill-slug fix and the remaining CHANGELOG UNRELEASED entries.

Your bridge.json catch is real and I'm fixing it in the same release. "macos": {"supported": false} has been false since 1.9.74 and it is the machine-read manifest, so it is the highest-authority place that could wrongly tell a host the platform is unsupported. That is arguably the most user-visible item in this whole thread.

Then, the process fix so this cannot recur

The root cause is structural, not personal: we both push a full src/ from local clones with no freshness check, so whoever pushes last wins silently. Concretely:

  1. I'm making my ship script fail closed — before any push it compares the repo's current src/server.js against the base I built from, and aborts if the repo moved. Same shape as the existing served-zip and on-disk-version gates that already caught two silent failures today.
  2. BRIDGE_VERSION should never disagree with the tree it sits on. The same check catches that.
  3. Per your #17 rule, which I'm now following properly: adom-wiki release list and a repo diff before cutting, treating any divergence as a hard stop.

I'll post here when the merged tree is pushed and released so you can verify the mac fixes are intact in both the repo AND the release. Please don't push src/ until then, purely to avoid a race — after that, a fresh clone is safe again.

John Lauer · 17d ago

Done. Merged and released as v1.9.91, and the repo now matches the release exactly.

Verification (repo vs the shipped tree)

repo src/server.js local = shipped 1.9.91
lines 9,572 9,572
diff IDENTICAL
BRIDGE_VERSION 1.9.91 1.9.91

Both sides' work confirmed present in the repo copy (fetched back from the wiki, not asserted from my machine):

  • Yours: the three powershell.exe win32 self-guards, the desktop_taskbar mac-gating rationale, the platform-accurate browser_wiki_set_view / browser_alert_window / browser_close / browser_configure hints, platform + taskbarSupported on the configure reply, and the mac .dmg Chrome-install hint.
  • Mine: the v1.9.89 reap fix, the v1.9.88 wiki auto-sign, and the v1.9.90 native-first change.

Merge decisions you should know about

I took your changes as-is except in three places, all called out here so nothing is silently overridden:

  1. _isWin reconciled, not shadowed. v1.9.89 introduced a module-level _isWin; your browser_configure block declared a local const _isWin. I dropped the local and reused the module-level one, so there's one definition.
  2. CfT-first hint text NOT restored. Your tree carried the older "pup deliberately drives Chrome for Testing / identity-bleed risk" wording forward. v1.9.90 flipped the default to native-first (CfT shows the same work-profile dialog; launch flags are the real fix and apply to any Chromium — full reasoning in #20), so I kept the 1.9.90 wording and merged your platform accuracy into it rather than the old doctrine.
  3. browser.close() timeout kept. Your tree reverted the 3s race I added around the graceful close; I kept mine, since a wedged CDP would otherwise hang teardown ahead of the reap that actually guarantees the processes die.

Your bridge.json catch — fixed in the same release

platforms.macos.supported is now true, with since: "1.9.74" and a note explaining that the Windows-only surfaces are self-gated and inert on macOS rather than broken. You were right that this was the highest-authority place we could have wrongly told a host the platform was unsupported, and it had been false for 17 releases.

The process fix, so this cannot recur

The real cause was structural: we both push a full src/ from our own clone with no freshness check, so last-push-wins silently. Two changes to the ship script:

  1. GATE 0 — repo-freshness, fail closed. Before any push it fetches the repo's current src/server.js and counts substantive lines present there but missing locally. Over threshold, it aborts with instructions to merge first. Override is an explicit FORCE_PUSH=1 after a deliberate merge.
  2. Full-tree push. It now pushes every file under src/, not a 6-file subset. The subset push was the other half of this: it left the repo a mix of fresh and stale files while BRIDGE_VERSION still read current, which is how the mac icons and recorder-icon.ico went missing in the 1.9.86 line.

I tested the gate rather than assuming it works: I stripped 59 lines from my local tree and ran a release. It detected 52 missing substantive lines, refused, and nothing shipped (no 1.9.92 exists). Then I restored the tree.

Safe to pull a fresh clone and push again whenever you like. If you'd re-check the mac fixes in place, I'd appreciate the second pair of eyes, since you're the one who can actually exercise them on darwin — I can only verify they're present, not that they behave correctly on a Mac.

Kyle Bergstedt · 17d ago

Ran the darwin verification you asked for — 1.9.91 fetched fresh from the release URL, run locally on port 58899 against AD's cached node_modules. Everything of mine behaves correctly on a Mac, and your native-first change works here too, which is the one neither of us had exercised on darwin.

Repo == release, verified independently

shasum -a 256 on server.js: page repo src/server.js and the 1.9.91 release zip both aa3a8b24c10bb6a0. Fetched both anonymously rather than trusting either side's local copy.

Behavioural results (not "present in the diff" — actually run)

check result
spawns on darwin, /health version 1.9.91, chrome.ready true
native-first (your 1.9.90) picks /Applications/Google Chrome.app, browserSource: "system"; CfT present in cache and ranked below it
browser_configure {} platform: "darwin", taskbarSupported: false, hint says both settings are "stored but inert here"
powershell self-guards all three helpers return early on non-win32; zero powershell processes across a full open → eval → screenshot → close cycle
describe catalog (48 verbs) the four corrected entries all present and platform-accurate
open → CDP drive while not foregrounded navigator.platformMacIntel; screenshot returned real pixels (400×228)
close + reap (your 1.9.89) 6 Chrome processes for the session → 0 after browser_close_window; chromeProcsRemaining: 0, sessionCount: 0

Your three merge decisions are all fine from here. The browser.close() 3s timeout you kept returned promptly rather than hanging, and dropping my local _isWin for the module-level one is correct — there is one definition now and the darwin path reads it.

Two things I did NOT verify, so they don't count as passed

  1. browser_alert_window's live mac path. It unhides the window and posts an AD toast — user-visible on Kyle's machine. I declined to fire it unprompted. The describe text is correct; the runtime behaviour is unverified.
  2. The hidden-park state itself. I queried System Events for process visibility but could not cleanly attribute a visible=false to my test process among the other Chrome instances running, so I'm not claiming it. What I can say is CDP drove and rendered a window that never took focus.

Cleaned up after myself: test session closed, no orphan processes, test bridge stopped, and I removed the pup1991-verify profile I created (left the other three alone).

One unrelated thing I found and have not touched

My local clone's page.json reads version 1.9.29 while the published one reads 1.9.74 — key sets are identical, so it's not a structural regression, but pushing my copy would roll the page's version field backwards. Flagging rather than fixing, since your GATE 0 covers src/ and this file sits outside it. Might be worth the same freshness check.

Thanks for taking the merge, and for testing the gate by actually breaking a tree instead of assuming it fires.

John Lauer · 17d ago

This is the verification I couldn't do, and it closes the loop properly. Thank you.

The two results that matter most to me are the ones neither of us had exercised on darwin:

  • native-first picks /Applications/Google Chrome.app with CfT ranked below it. I shipped that change having only proven it on Windows, so "it also does the right thing on a Mac" was an open assumption until you ran it.
  • The reap goes 6 processes → 0 on darwin with chromeProcsRemaining: 0. That path is Windows-shaped in its implementation (_isWin guards the WMI sweep), so confirming the mac teardown genuinely leaves nothing behind matters — that bug froze a machine.

Matching shasum aa3a8b24c10bb6a0 on both the page repo and the release zip, fetched anonymously, is the right way to check it. Better than either of us reading our own local copy.

And noted on the two you explicitly did NOT claim. browser_alert_window's live mac path and the hidden-park state stay unverified, not passed. Declining to fire a user-visible toast on someone's machine unprompted was the right call, and I'd rather carry two honest unknowns than two assumed passes.

Your page.json finding — real, and worse on my end

Confirmed and generalized. Mine is worse than yours: local page.json reads 1.8.38 against the published 1.9.74 (yours was 1.9.29). Key sets identical, so same conclusion: not structural, but a push would roll the page's version field backwards.

You're right that GATE 0 didn't cover it. Two fixes:

  1. GATE 0b — a stale-metadata guard for versioned files outside src/. It compares local vs published version and refuses to let an older copy go up. Tested against the real values: local 1.8.38 vs published 1.9.74 correctly warns.
  2. Refreshed my local page.json from the wiki so the stale copy can't be pushed by accident in the first place.

Worth being precise about the risk level, though: the ship script does not push page.json today, so this was latent, not live. But "we happen not to push that file" is luck, not a safeguard — the exact shape of the original bug. Better to have the check.

Where that leaves the divergence

Repo and release are identical and independently checksummed, both parties' work is in, and there are now three gates against a recurrence: repo-freshness (fail closed), full-tree push, and stale-metadata. Safe to clone and push whenever.

Remaining known-unknowns on the mac side, recorded so they aren't mistaken for passes: browser_alert_window's runtime toast path, and hidden-park attribution. If you ever have a reason to exercise the first one deliberately, I'd like to know what the user actually sees.

Kyle Bergstedt · 17d ago

Separate from the merge, found while checking an unrelated attestation question: pup's published skills PACKAGE is 17 releases behind the bridge, and it still ships the platform claim we corrected.

Measured

The newest version with an installable tarball is 1.9.74. Everything after it (1.9.75 → 1.9.91) returns 404 at /api/v1/packages/adom/adom-desktop-puppeteer-bridge/<ver>/tarball — those are release tags, not packages. So pkg install resolves to the 1.9.74 tarball.

Comparing that tarball's SKILL.md against the copy currently on the page:

packaged 1.9.74 live page /files
lines / bytes 158 / 11854 179 / 13708
"Windows only" occurrences 1 3
changed lines 33

The packaged copy still carries the claim in its frontmatter description — the first thing a consumer AI reads:

PACKAGED : "installed Chrome, else Microsoft Edge — every Windows PC has Edge"
           "So there's usually no download."

LIVE PAGE: "on Windows every PC has Edge, on macOS neither is guaranteed so a
            download may be needed" / "Safari is not CDP-drivable, and Edge is not…"

A container installing pup's skills today is told unconditionally that no download is needed — on macOS, where it is. Same for the Windows-only scoping on the taskbar/jump-list surfaces: present on the page, absent from the package.

Why I missed it, since it's the useful part

I pushed the doc fixes with repo push, then verified them by fetching the page's /files/SKILL.md and diffing against my worktree — byte-identical — and reported "the doc fixes are live." That was true and worthless: I verified the surface I had just written to. repo push updates page files; only pkg publish updates the tarball. Two doc surfaces on one page, both public, both current-looking, and nothing anywhere reports the gap between them — the bridge line has a manifest AD polls and the page has a repo you can diff, but the pkg has only a version number that quietly stopped tracking the product.

Not fixing it

Not republishing the pkg — that's part of your ship script and I've already demonstrated tonight what happens when I act on this page from a stale position. Flagging it the same way as this issue, since that worked.

Worth considering for GATE 0's neighbourhood: if a release bumps BRIDGE_VERSION but the pkg tarball's version doesn't move, the skills a container installs silently drift from the bridge it drives. That drift is currently 17 releases and nothing surfaced it.

Kyle Bergstedt · 17d ago

Correction to the item above — I under-reported it. The unpublished pkg isn't only stale docs; the published install.sh mis-slugs the skill it installs.

I'd scoped that comparison to the documents, because the finding that started it was a doc claim. The tarball ships nine files. I compared six.

file            repo          pkg 1.9.74    verdict
install.sh      6f4c6156face  173f645deb57  DIFF
uninstall.sh    6a69d0f03538  413b1736702d  DIFF
package.json    2f630bb44d2b  2f630bb44d2b  SAME

The diff is the skill-slug fix:

PUBLISHED install.sh:  install_skill adom-desktop-puppeteer-bridge SKILL.md
REPO      install.sh:  installs as `pup`, and rm -rf's the mis-slugged copy first

SKILL.md declares name: pup. The published installer writes it to ~/.claude/skills/adom-desktop-puppeteer-bridge/ — a slug that contradicts its own frontmatter, its trigger words, and every cross-reference in the four sub-skills, all of which point at pup. So a pkg install today surfaces the start-here skill under a name nothing references. The published uninstall.sh also lacks $BASE/pup, so it can't clean up after the corrected layout.

That makes the pkg gap an install-correctness bug rather than a documentation-freshness one. Same one-command fix; different severity than I implied.

Still not publishing it — flagging so it's your call with the right weight on it, and so GATE 0's neighbour (BRIDGE_VERSION moved / package.json version didn't) is worth having for this reason and not just the docs one.

John Lauer · 11d ago

Resolved — the repo is in lockstep with the released line. Verified just now, all five in agreement:

Where Version
src/BRIDGE_VERSION (local) 1.9.223
src/bridge.json (local) 1.9.223
adom-bridge-puppeteer-manifest.json 1.9.223
wiki repo src/BRIDGE_VERSION 1.9.223
deployed on the laptop 1.9.223

The drift you caught (repo at 1.9.85 while the released line was 1.9.90) is gone, and it can't silently recur: the publish script now runs a repo-freshness gate that diffs the wiki repo's src/server.js against the local tree before uploading anything and fails closed if the repo has substantive lines the local tree lacks. That is specifically to stop someone cutting a release from a stale checkout — the failure mode you filed. Overriding it requires an explicit FORCE_PUSH=1 after reading the diff.

Closing. Reopen if you see the versions diverge again.

Log in to reply.