Skip to content

Decree sharing, Linux ARM64, and a 276MB debug-symbol bug in the shipped binary - #7

Merged
hotpixelgroup merged 1 commit into
masterfrom
sharing-and-arm
Jul 27, 2026
Merged

Decree sharing, Linux ARM64, and a 276MB debug-symbol bug in the shipped binary#7
hotpixelgroup merged 1 commit into
masterfrom
sharing-and-arm

Conversation

@hotpixelgroup

Copy link
Copy Markdown
Owner

Two features, plus a live bug found while building them.

Linux ARM64 prebuilt nodes

ubuntu-24.04-arm is GA and free for public repos, so it is one matrix entry —
but a published arm64 tarball would have been unreachable without teaching
both installers the aarch64 slug, so those land together (install.sh and the
console's PREBUILT_SLUGS, accepting both aarch64 and arm64 spellings).

x86_64 is pinned from ubuntu-latest to ubuntu-24.04. latest is mid-migration
to 26.04, whose CMake 4 is hostile to this tree's cmake_minimum_required(3.22),
and a release tag is the worst possible moment to discover that.

The live bug this turned up

The currently published vibes-node-linux-x86_64 is 291 MB, of which
276 MB is DWARF. I pulled the release asset and parsed its ELF section
headers: .debug_info alone is 165 MB, while .text is 8.7 MB.

Cause: the default build type is RelWithDebInfo, and Linux embeds debug info in
the ELF while macOS keeps it in a separate .dSYM — which is exactly why macOS
looked healthy at 6.9 MB and nobody noticed.

The Strip step was supposed to prevent this and silently didn't. It ended in
2>/dev/null || true, and its own ls -lh printed 292M while the job reported
success. Now: build Release, strip without masking errors, and fail the job
if bitcoind exceeds 60 MB.

Honest caveat for the commit record: binaries built on 24.04 require
GLIBCXX_3.4.32 (GCC 13). I verified this against the published artifact —
glibc floor is 2.34, so that is not the constraint, but libstdc++ is: this will
not run on Debian 12 / Raspberry Pi OS Bookworm, which tops out at 3.4.30. It
runs on Trixie and Ubuntu 24.04+. Those users fall back to compiling, which is
the already-tested graceful path.

Decree sharing

A decree travels as a wish, never a patch. The recipient's own agent writes
their own code under their own guardrails. Shipping a diff would convert "a
stranger suggests words to your agent" into "a stranger ships C++ into your
Bitcoin node" — that is deliberately out of scope and noted in the schema.

Promulgate produces a vibe1.<base64url> token in three envelopes:

  • a localhost link carrying it in the URL fragment — never the query, so the
    payload never reaches the server or its logs
  • a markdown block that always carries the decree in readable plain text
    beside the token; base64 alone, pasted into a Bitcoin node, is
    indistinguishable from malware and deserves to be refused
  • a .vibe.json file for anything past the URL budget (live length meter,
    disables the link button past 1800 chars)

The link is built from location.origin, never location.href — the console
URL carries ?key= and href would paste the operator's session key into a chat
channel. That is the highest-consequence possible bug in this feature.

Receiving is entirely client-side, and accepting does exactly one thing: fill
the textarea.
It calls no API. A shared decree therefore can do nothing the
operator could not have typed, and the entire existing gauntlet — the YOLO
confirm, consensus judgement on the real diff, the smoke test — applies
unchanged. A paste box backs up the link, because a link cannot be relied on:
SameSite=Strict withholds the cookie on cross-site navigation and the
recipient's port may differ.

Verified against a hostile payload

Round-tripped a decree containing <script>, an onerror img, and a bidi
override:

  • no handler fired; every payload-bearing element has zero child nodes — the
    markup became inert text
  • the bidi override was detected and flagged, not silently stripped (stripping
    would change the operator's decree behind their back)
  • a claimed consensus flag shows a warning; an empty one grants no reassurance,
    because a claim of safety may never be believed
  • the textarea stayed empty until accept
  • link length 375 chars, and it contains no key

Also fixes a selector that never matched: the Book of Decrees had no
book-section id, so Repent stayed live during first-run setup.

Checklist

  • I ran it — endpoint, round-trip, XSS, bidi, and key-leakage all exercised
  • python3 -m py_compile, sh -n on installers
  • src/ untouched — consensus unaffected

Two features.

LINUX ARM64
  ubuntu-24.04-arm is GA and free for public repos, so it is one matrix
  entry — but the artifact would have been unreachable without teaching
  both installers the aarch64 slug, so those land together. x86_64 is
  pinned from ubuntu-latest to ubuntu-24.04: latest is migrating to
  26.04, whose CMake 4 is hostile to this tree's
  cmake_minimum_required(3.22), and a release tag is the worst moment to
  discover that.

  Investigating the ARM build turned up a live bug in the shipped x86_64
  artifact: it is 291MB of which 276MB is DWARF, because the default
  build type is RelWithDebInfo and Linux embeds debug info in the ELF
  where macOS keeps it in a separate .dSYM — which is why macOS looked
  fine at 6.9MB. The Strip step was supposed to catch this and silently
  did not: it ended in '2>/dev/null || true', and its own ls printed
  292M while the job reported success. Now builds Release, strips
  without masking errors, and fails the job if bitcoind exceeds 60MB.

DECREE SHARING
  A decree travels as a wish, never a patch. The recipient's own agent
  writes their own code under their own guardrails; shipping a diff
  would turn 'a stranger suggests words to your agent' into 'a stranger
  ships C++ into your Bitcoin node'.

  Promulgate produces a vibe1.<base64url> token in three envelopes: a
  localhost link carrying it in the URL *fragment* (never the query, so
  it never reaches the server or its logs), a markdown block that always
  carries the decree in readable plain text beside the token, and a
  .vibe.json file. The link is built from location.origin and never
  location.href, because the console URL carries ?key= and href would
  paste the operator's session key into a chat channel.

  Receiving is entirely client-side and the accept action does exactly
  one thing: fill the textarea. It calls no API, so a shared decree can
  do nothing the operator could not have typed, and the whole existing
  gauntlet — YOLO confirm, consensus judgement on the real diff, the
  smoke test — applies unchanged. A paste box backs up the link, which
  cannot be relied on: SameSite=Strict withholds the cookie on
  cross-site navigation and the recipient's port may differ.

  Verified against a deliberately hostile payload: script tags and an
  onerror img render as inert text (every payload element has zero child
  nodes), no handler fires, bidi overrides are detected and flagged
  rather than silently stripped, a claimed-consensus flag shows a
  warning while an empty one grants no reassurance, and the textarea
  stays empty until the operator accepts.

Also fixes a selector that never matched: the Book of Decrees had no
book-section id, so Repent stayed live during first-run setup.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@hotpixelgroup
hotpixelgroup merged commit 201b658 into master Jul 27, 2026
2 checks passed
@hotpixelgroup
hotpixelgroup deleted the sharing-and-arm branch July 27, 2026 07:03
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