# Packaging failures

> Non-darwin package abort, missing renderer patch anchors, ad-hoc codesign retry, xattr quarantine, and verify required ASAR entries.

- Repository: sashimikun/grok-bot-0.18-reconstructed
- GitHub: https://github.com/sashimikun/grok-bot-0.18-reconstructed
- Human docs: https://grok-wiki.com/public/docs/sashimikun-grok-bot-0-18-reconstructed-c774cc9a5c15
- Complete Markdown: https://grok-wiki.com/public/docs/sashimikun-grok-bot-0-18-reconstructed-c774cc9a5c15/llms-full.txt

## Source Files

- `scripts/package-macos.mjs`
- `scripts/lib/codesign.mjs`
- `scripts/lib/macos-package-verification.mjs`
- `scripts/lib/router-renderer-patch.mjs`
- `scripts/verify.mjs`
- `tests/publication-packaging.test.mjs`

---

---
title: "Packaging failures"
description: "Non-darwin package abort, missing renderer patch anchors, ad-hoc codesign retry, xattr quarantine, and verify required ASAR entries."
---

`npm run package` runs `npm run check` then `node scripts/package-macos.mjs`. That script is darwin-only: it builds the fidelity reconstructed ASAR (`buildFidelityReconstructedAsar`), copies the checksum-pinned 0.18 Electron shell with `/usr/bin/ditto`, replaces `Contents/Resources/app.asar` and `app.asar.unpacked`, rewrites reconstructed identity in `Info.plist`, strips extended attributes with `/usr/bin/xattr -cr`, ad-hoc signs with identity `-`, then verifies the signature and package invariant. Default output is `dist/Grok Bot 0.18 Reconstructed.app` unless `GROK_BOT_OUTPUT_APP_NAME` sets a different basename under `dist/`.

<Warning>
Packaging does not produce a Windows installer, a notarized Developer ID signature, or a clean-source renderer. The packaged UI is the shipped 0.18 renderer plus the exact Settings Router patch. Failures below are abort-the-build, not launch-time router errors.
</Warning>

## Abort order

| Gate | Owner | Typical abort |
| --- | --- | --- |
| `npm run check` | `package` script | Typecheck or `node --test tests/*.test.mjs` fails before packaging starts |
| `process.platform !== "darwin"` | `scripts/package-macos.mjs` | `The reconstructed macOS application can only be packaged on macOS.` |
| Settings chunk scan | `applyOriginalRendererRouterPatch` | `Expected one original Settings registry and panel chunk, found N/M.` |
| Exact string replace | `replaceExactlyOnce` | `Original renderer <label> anchor is missing or ambiguous.` |
| Official shell / ASAR hashes | `verifyOfficialMacReference` | `Official Mac shell reference drifted` / `Official Mac app.asar reference drifted` |
| Staged pack | `packStagedAppWithIntegrity` | `Staged package changed or ASAR drifted after snapshot` |
| Ad-hoc sign | `signAppBundleAdHoc` | `/usr/bin/codesign exited with <code>` after one retry |
| Deep verify | `/usr/bin/codesign --verify --deep --strict` | Non-zero `codesign` exit |
| Reconstructed invariant | `verifyReconstructedMacPackage` | Official payload copied, Mach-O mismatch, or unpacked runtime drift |
| Independent verify | `npm run verify` | Missing ASAR entry, native file, bundle id, or signature |

Success log from `package-macos.mjs`:

```text
Packaged application: <outputApp> (<nodeFileCount> native manifest entries, <runtimeFileCount> unpacked runtime files)
```

## Non-darwin abort

The reconstructed app is a macOS Apple Silicon Electron shell. `scripts/package-macos.mjs` throws immediately when `process.platform !== "darwin"` and never stages `dist/`. `scripts/package-fidelity-diagnostic.mjs` uses the same platform gate (`The fidelity diagnostic app can only be packaged on macOS`).

<Note>
Linux or Windows hosts can still run `npm run check`, `npm test`, and `npm run publication:check`. They cannot emit `dist/Grok Bot 0.18 Reconstructed.app`.
</Note>

Required host tools (hard-coded absolute paths in `SYSTEM_TOOLS`):

| Tool | Path | Packaging use |
| --- | --- | --- |
| `ditto` | `/usr/bin/ditto` | Copy cached `Grok Bot.app` into `dist/` |
| `xattr` | `/usr/bin/xattr` | `xattr -cr <outputApp>` |
| `plutil` | `/usr/bin/plutil` | Bundle id, display name, URL types, drop `ElectronAsarIntegrity` |
| `codesign` | `/usr/bin/codesign` | Ad-hoc sign and `--verify --deep --strict` |

Missing Xcode Command Line Tools surface as spawn/exit errors from those binaries, not as a custom packaging message.

## Missing renderer patch anchors

Default packaging keeps the checksum-pinned shipped renderer (`checksum-pinned-artifact-runtime`) and installs Settings Router by rewriting two original chunks under `dist/renderer/assets/*.js`.

Anchors that must appear **exactly once** in the scanned `.js` files:

| Label | Role |
| --- | --- |
| `settings registry` | Insert `{id:"router",label:"Router",icon:"git-branch"}` into the Settings nav array |
| `component insertion` | Prefix `function Sa(s){` with `RRouterPanel` / `RBoxRuntime` / `RRouterUsage` |
| `Router panel switch` | Route `x==="router"` to `RRouterPanel` |
| `Usage panel switch` | Replace Usage panel body with `RRouterUsage` |

Scan rule: exactly one registry candidate (`REGISTRY_BEFORE`) and exactly one panel candidate (`COMPONENT_ANCHOR` **and** `GENERAL_BEFORE` **and** `USAGE_BEFORE`). Any other cardinality throws:

```text
Expected one original Settings registry and panel chunk, found <registryCount>/<panelCount>.
```

A found string that is missing or duplicated throws:

```text
Original renderer <label> anchor is missing or ambiguous.
```

<AccordionGroup>
<Accordion title="Usual causes">

- `npm run bootstrap` did not hydrate `src/app/dist/renderer` from the pinned 0.18 `app.asar`.
- `GROK_BOT_RENDERER_SOURCE` replaced `dist/renderer` with a Vite (or other) tree that lacks the minified 0.18 Settings strings. Fidelity overlay does **not** restore `dist/renderer` when the renderer mode is `checksum-pinned-artifact-runtime`, so the patch still runs against the override.
- The shipped chunks were edited, minified differently, or already patched so the `before` strings no longer match once.

</Accordion>
<Accordion title="What packaging does not do">

`frontend/` is a design workspace. `npm run frontend:build` does not become the packaged UI unless you override the renderer, which then breaks these anchors. The patch writes `dist/renderer-router-extension.json` (`schemaVersion` 1, `mode` `original-renderer-settings-extension`) with per-chunk original/patched SHA-256 records.

</Accordion>
</AccordionGroup>

## Quarantine and xattr

After `ditto` copies the official runtime app to the output bundle, packaging runs:

```sh
/usr/bin/xattr -cr "dist/Grok Bot 0.18 Reconstructed.app"
```

The source DMG's quarantine/provenance belongs to Anysphere's signed artifact. Leaving those attributes on the reconstructed bundle makes Gatekeeper reject a valid **ad-hoc** signature before launch. `xattr` failure is a hard abort (`/usr/bin/xattr exited with <code>`). Do not skip this step to “keep” Gatekeeper metadata.

## Ad-hoc codesign retry

Signing is local-only. Identity is `AD_HOC_CODESIGN_IDENTITY` (`"-"`). Arguments:

```text
--force --deep --timestamp=none --sign - <bundle>
```

`signAppBundleAdHoc` invokes `/usr/bin/codesign` with non-interactive stdio (`ignore` / `inherit` / `inherit`). Empty target paths throw `An explicit application bundle path is required for ad-hoc signing.`

Before sign, packaging deletes `Contents/_CodeSignature`, then:

```mermaid
stateDiagram-v2
  [*] --> Unsigned: remove _CodeSignature
  Unsigned --> Signed: signAppBundleAdHoc pass 1
  Unsigned --> RetryWarned: pass 1 fails
  RetryWarned --> Signed: signAppBundleAdHoc pass 2
  RetryWarned --> Aborted: pass 2 fails
  Signed --> Verified: codesign --verify --deep --strict
  Verified --> [*]: verifyReconstructedMacPackage
  Aborted --> [*]
```

First-pass failure prints:

```text
Initial ad-hoc signing pass failed; retrying once: <error>
```

That retry exists because macOS can transiently deny replacing a nested framework signature while the copied runtime was still in use. A second pass is expected to succeed after the kernel releases the code object. There is **no** third attempt. A failed retry is the original `codesign` exit:

```text
/usr/bin/codesign exited with <code>
```

<Warning>
Do not weaken this gate (Developer ID, `--no-strict`, skipping `--deep`, or swallowing the retry). CONTRIBUTING requires checksum, bundle identity, and code-signing checks to stay fail-closed.
</Warning>

## Official reference vs reconstructed payload

`verifyOfficialMacReference` hashes the cached official app **before** the reconstructed ASAR is swapped in:

| Artifact | Path in official app | Expected SHA-256 |
| --- | --- | --- |
| Mach-O shell | `Contents/MacOS/Grok Bot` | `7fcdbad6228f0b7b90078c9f81968d9246c7f904e62cc5f2bce96dc504e3383e` |
| Official `app.asar` | `Contents/Resources/app.asar` | `6665408168466f9cacc6087e917890c17f59d2e2e9c2404a5c4a59ad79c1de58` |

`verifyReconstructedMacPackage` then requires:

- signature-excluded Mach-O structural match (`expectedSignatureExcludedMachOHash` `0076e3c5a6fda431b0a0c5bf25510c4b37562ff178d4f2053bac32f3885d6875`)
- reconstructed shell hash **must not** equal the official signed shell hash
- reconstructed `app.asar` hash **must not** equal the official ASAR hash
- unpacked trees `dist/deps`, `dist/native`, `dist/node-deps` byte-identical to the staged unpack
- `dist/deps/runtime-deps-manifest.json` with `platform` `darwin`, `arch` `arm64`, non-empty `nodeFiles`, and `resolutionClosure.mode` `byte-exact-sibling-package-copy`

Typical messages: `Official Mac shell reference drifted`, `Reconstructed package must not copy the official signed shell`, `Reconstructed package must not copy the official app.asar`, `Missing unpacked runtime root dist/deps`, `Packaged unpacked runtime drift at <path>`.

Plist mutations that must succeed (otherwise `plutil` exits non-zero):

- remove `ElectronAsarIntegrity`
- `CFBundleIdentifier` → `com.anysphere.sand.reconstructed`
- `CFBundleDisplayName` → `Grok Bot 0.18 Reconstructed`
- replace `CFBundleURLTypes` with a single `sand` URL scheme

`CFBundleName` / `CFBundleExecutable` stay `Grok Bot` so Electron helper names still match the reused 0.18 ABI.

## Independent verify: required ASAR entries

`npm run verify` (`scripts/verify.mjs`) inspects the selected `.app`, not `.build/app.asar`.

<ParamField body="--app" type="string">
Absolute path to a `.app` bundle. Default is `outputApp` (`dist/Grok Bot 0.18 Reconstructed.app`, or `GROK_BOT_OUTPUT_APP_NAME`). Usage: `node scripts/verify.mjs [--app /absolute/path/to/App.app]`.
</ParamField>

`resolvePackagedAppArtifacts` rejects non-`.app` paths (`Expected a .app bundle path`). ASAR listing is `@electron/asar` `listPackage` (entries with a leading `/`).

Required ASAR files:

```text
/dist/electron-main/main.cjs
/dist/electron-dev-controls/main.cjs
/dist/electron-preload/preload.cjs
/dist/electron-preload/preload-dev-controls.cjs
/dist/electron-preload/preload-webview.cjs
/dist/electron-preload/preload-vnc.cjs
/dist/node-agent-coordinator/main.cjs
/dist/host/host-main.cjs
/dist/host/agent-isolation/agent-store-worker.cjs
/dist/host/agent-isolation/transcript-mirror-worker.cjs
/dist/host/extensions/box-store-sync/box-store-vacuum-worker.cjs
/dist/host/extensions/content-search/search-index-worker.cjs
/dist/local-exec-daemon/main.cjs
/dist/renderer/index.html
/dist/reconstruction-build.json
/dist/runtime-composition-audit.json
/package.json
```

Missing any of those throws `ASAR is missing <path>`.

Also required:

| Check | Failure |
| --- | --- |
| ≥ 1,000 `// src/` markers in `src/app/dist` electron-main + host-main | `Expected at least 1,000 surviving evidence source markers, found N` |
| Unpacked `dist/deps/better-sqlite3/build/Release/better_sqlite3.node` | `access` fail |
| Unpacked `dist/native/sand-webauthn-signer` | `access` fail |
| Icon `dist/renderer/assets/app-icon-C7NKj2u7.png` vs `frontend/manifests/renderer-runtime-assets.json` | `ASAR is missing …` or `Packaged app icon differs from its renderer runtime manifest` |
| Any `dist/renderer/**/*.map` | `Packaged renderer contains source maps` |
| Node ABI entries in **both** ASAR and unpack (`tree_sitter_runtime_binding.node`, `tree_sitter_bash_binding.node`, `node-addon-api` / `node-gyp-build` `package.json`) | `ASAR is missing generated Node runtime entry <path>` |
| `CFBundleIdentifier` | `Unexpected reconstructed bundle ID` (must be `com.anysphere.sand.reconstructed`) |
| `CFBundleDisplayName` | `Unexpected reconstructed display name` |
| `ElectronAsarIntegrity` still in plist | `Stale ElectronAsarIntegrity metadata remains in the reconstructed application` |
| URL types | `Reconstructed application has no sand URL registration` |
| `codesign --verify --deep --strict` | `codesign` non-zero exit |

For `renderer.mode === "checksum-pinned-artifact-runtime"` (the `npm run package` path), provenance must bind `upstreamAppAsarSha256` to `6665408168466f9cacc6087e917890c17f59d2e2e9c2404a5c4a59ad79c1de58` and every `dist/renderer/` file must match that inventory. Clean-source renderer extra checks apply only if composition is `clean-source` (not the default package).

<RequestExample>
```sh title="Re-verify the default dist bundle"
npm run verify
```
</RequestExample>

<ResponseExample>
```text title="verify success (shape)"
Verified packaged ASAR <app>/Contents/Resources/app.asar.
Verified <N> executable clean-source runtimes, deterministic ASAR hashes, native dependencies, bundle identity, and code signature.
Documented non-clean runtime boundaries: <runtime names>. Evidence markers checked: <count>. Repository: <repoRoot>
```
</ResponseExample>

## Recover a failed package

<Steps>
<Step title="Confirm darwin and tools">
Run `uname -s` (`Darwin`) and that `/usr/bin/codesign`, `/usr/bin/xattr`, `/usr/bin/ditto`, and `/usr/bin/plutil` exist. Then `npm run check`.
</Step>
<Step title="If the abort is bootstrap-shaped">
DMG / `app.asar` checksum and hydration failures belong to bootstrap, not this page. Re-run `npm run bootstrap` so `src/app/dist` and the cached `Grok Bot.app` match the pinned 0.18 identities.
</Step>
<Step title="If the abort is a renderer anchor">
Unset `GROK_BOT_RENDERER_SOURCE`. Confirm `src/app/dist/renderer/assets` still contains the original Settings chunks (search for `id:"general",label:"General"`). Do not hand-edit those minified files.
</Step>
<Step title="If the abort is codesign">
Quit any running `Grok Bot` / reconstructed app that still holds the copied framework, re-run `npm run package`, and look for the one-shot retry warning. A second failure is not a quarantine issue if `xattr -cr` already ran; inspect `codesign` stderr.
</Step>
<Step title="Verify the bundle, then smoke">
`npm run verify` then `npm run smoke`. Do not ship a bundle that fails `--deep --strict` or is missing a required ASAR path.
</Step>
</Steps>

<Tip>
`GROK_BOT_OUTPUT_APP_NAME` only changes the `dist/` basename. Verify with `--app` if you set it, or `verify` will look at the default `Grok Bot 0.18 Reconstructed.app`.
</Tip>

## Next

<CardGroup>
<Card title="Package the macOS app" href="/package-macos-app">
Happy-path `npm run package` compile, patch, identity, sign, and output bundle.
</Card>
<Card title="Bootstrap failures" href="/bootstrap-failures">
LFS pointer DMGs, checksum mismatch, and `src/app/dist` hydration errors that starve packaging.
</Card>
<Card title="Verify and smoke" href="/verify-and-smoke">
`npm run verify` vs `npm run smoke`, updater `SAND_DISABLE_*` defaults.
</Card>
<Card title="Contributing" href="/contributing">
Required `check` / `package` commands. Do not weaken checksum or signing gates.
</Card>
</CardGroup>
