# Verify and smoke

> npm run verify required ASAR paths and evidence markers; npm run smoke native e2e with 12s timeout; updater guard SAND_DISABLE_* defaults.

- 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/verify.mjs`
- `scripts/smoke.mjs`
- `scripts/native-e2e-check.mjs`
- `scripts/lib/build-asar.mjs`
- `tests/reconstructed-updater-guard.test.mjs`
- `package.json`

---

---
title: "Verify and smoke"
description: "npm run verify required ASAR paths and evidence markers; npm run smoke native e2e with 12s timeout; updater guard SAND_DISABLE_* defaults."
---

`npm run verify` and `npm run smoke` are post-package gates on the reconstructed macOS app. `verify` (`scripts/verify.mjs`) fail-closes on ASAR membership, unpacked natives, composition provenance, reconstructed identity, and `codesign --verify --deep --strict`. `smoke` (`scripts/smoke.mjs`) calls `runNativeE2E` with `timeoutMs: 12_000` against the same default bundle and never launches unless the structural graph and `/Applications` placement pass. The Electron-main artifact fallback prepends an idempotent updater guard that sets `SAND_DISABLE_UPDATES`, `SAND_DISABLE_SENTRY`, and `SAND_DISABLE_TELEMETRY` with `??= "1"`.

`npm run package` signs the bundle and runs `verifyReconstructedMacPackage`; it does not invoke `scripts/verify.mjs`. After packaging, run verify (and smoke if you need a native observation) yourself.

## Commands

| Script | Implementation | Default target | Timeout |
| --- | --- | --- | --- |
| `npm run verify` | `node scripts/verify.mjs` | `outputApp` → `dist/Grok Bot 0.18 Reconstructed.app` | none (throws on first failure) |
| `npm run smoke` | `node scripts/smoke.mjs` | same `outputApp`; `structuralOnly: false` | **12_000 ms** |
| (direct) | `node scripts/native-e2e-check.mjs` | `dist/Grok Bot 0.18 Reconstructed.app`; default `timeoutMs: 15_000` | CLI `--timeout-ms` |

Override the verify bundle with an **absolute** path:

```sh
node scripts/verify.mjs --app /absolute/path/to/Grok\ Bot\ 0.18\ Reconstructed.app
```

`GROK_BOT_OUTPUT_APP_NAME` changes only the basename under `dist/`; it cannot retarget `/Applications`. For a production-startup observation against an installed copy, call native e2e directly:

```sh
node scripts/native-e2e-check.mjs --app /Applications/Grok\ Bot\ 0.18\ Reconstructed.app --timeout-ms 12000
```

<Note>
`npm run smoke` always points at `outputApp` under `dist/`. Production launch is refused unless `realpath(app)` is inside `/Applications`, so the default smoke command is a structural-plus-prerequisite run, not an in-place launch of the dist payload.
</Note>

## Verify

`scripts/verify.mjs` resolves `Contents/Resources/app.asar` and `app.asar.unpacked` via `resolvePackagedAppArtifacts`. Any missing path or mismatched hash throws. Success prints the ASAR path, clean-source runtime count, documented non-clean boundaries, evidence-marker count, and repo root.

### Evidence markers

Before ASAR checks, verify reads hydrated `src/app/dist/electron-main/main.cjs` and `src/app/dist/host/host-main.cjs` and counts lines matching `/^\/\/ src\//`. Fewer than **1,000** combined markers throws `Expected at least 1,000 surviving evidence source markers`.

### Required ASAR membership

These archive paths must appear in `listPackage(app.asar)` (leading `/` as stored by `@electron/asar`):

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

Unpacked natives that must exist on disk (not only in the ASAR listing):

- `app.asar.unpacked/dist/deps/better-sqlite3/build/Release/better_sqlite3.node`
- `app.asar.unpacked/dist/native/sand-webauthn-signer`
- `dist/node-deps/tree-sitter/build/Release/tree_sitter_runtime_binding.node`
- `dist/node-deps/tree-sitter-bash/build/Release/tree_sitter_bash_binding.node`
- `dist/node-deps/node_modules/node-addon-api/package.json`
- `dist/node-deps/node_modules/node-gyp-build/package.json`

Additional renderer constraints:

- `frontend/manifests/renderer-runtime-assets.json` must record `app-icon-C7NKj2u7.png` with a SHA-256; the packaged file must match bytes and hash.
- No `dist/renderer/**/*.map` source maps.
- `dist/renderer/index.html` must use file-relative `src="./assets/..."`.

### Composition and provenance

`dist/reconstruction-build.json` `runtimeComposition` must match `dist/runtime-composition-audit.json`. Each `buildManifest.outputs[]` entry is re-hashed from the ASAR.

| Runtime mode | Verify rule |
| --- | --- |
| `clean-source` | Must **not** ship `dist/recovered-source/...` for that runtime. Bundles must contain `// Deterministic clean-source`. Host/Electron-main require `dist/host-production-bindings.json` / `dist/electron-main-production-bindings.json` with `status: "validated-clean-source"` and no `src/app`, `dist/deps`, or `recovered/source-capsules` binding modules. Clean renderer must prove `frontend/src/main.tsx`, **11** reviewed route contracts, **5** composed feature surfaces, **0** findings, and must not activate `index-UbX-y3il.js`. |
| `artifact-fallback` | Must ship the recovered-source path (`dist/recovered-source/electron-main/main.cjs` or `.../host/host-main.cjs`) and a `sourceBundle`. Packaged `dist/electron-main/main.cjs` must equal `prepareReconstructedElectronMainArtifactFallback` of the immutable evidence bytes. |
| `checksum-pinned-artifact-runtime` (renderer) | Provenance `schemaVersion` 1, `upstreamAppAsarSha256` equals `6665408168466f9cacc6087e917890c17f59d2e2e9c2404a5c4a59ad79c1de58`, every inventoried file matches bytes/SHA-256, no undeclared renderer files. Default `npm run package` uses this renderer mode. |

Any other renderer mode throws `Unsupported packaged renderer mode`.

### Bundle identity and signature

| Check | Required value |
| --- | --- |
| `CFBundleIdentifier` | `com.anysphere.sand.reconstructed` |
| `CFBundleDisplayName` | `Grok Bot 0.18 Reconstructed` |
| `ElectronAsarIntegrity` | must be absent |
| URL schemes | `sand` present under `CFBundleURLTypes` |
| codesign | `codesign --verify --deep --strict` on the `.app` |

## Smoke and native e2e

`scripts/smoke.mjs` prints each diagnostic as `STATUS check: detail`, then `Smoke verification: PASS|FAIL|PREREQUISITE`.

```js
const report = await runNativeE2E({
  appPath: outputApp,
  payloadPath: outputApp,
  structuralOnly: false,
  timeoutMs: 12_000,
});
process.exitCode = report.status === "pass" ? 0 : report.status === "prerequisite" ? 2 : 1;
```

Direct `native-e2e-check.mjs` flags: `--app`, `--payload`, `--structural-only`, `--json`, `--timeout-ms`. Unknown flags throw.

```mermaid
stateDiagram-v2
  [*] --> OpenPayload: runNativeE2E
  OpenPayload --> Prerequisite: missing app or unreadable ASAR
  OpenPayload --> Structural: inspectPackagedArtifacts + verifyEntrypointGraph
  Structural --> SkipLaunch: .app requested and a structural check failed
  SkipLaunch --> Prerequisite: runtime:launch skipped
  Structural --> Launch: .app, structural pass
  Launch --> Prerequisite: not Darwin, not under /Applications, unsigned, or no use-mock-keychain
  Launch --> Observe: isolated profile, 12s window, --use-mock-keychain
  Observe --> Pass: renderer present, host/coordinator absent, no fatal or opaque-fallback logs
  Observe --> Fail: early exit, missing renderer, unexpected host/coordinator, fatal or opaque-fallback logs
```

### Structural artifacts (smoke)

Smoke’s `REQUIRED_PACKAGED_ARTIFACTS` is a **subset** of verify, plus a clean-renderer provenance file that the default fidelity package does **not** ship:

- `package.json` with `main === dist/electron-main/main.cjs` and `sandLab` absent or exactly `false`
- `dist/electron-main/main.cjs`, preloads, coordinator, host, local-exec daemon, `dist/renderer/index.html`
- `dist/renderer/renderer-source-provenance.json` (clean-source renderer only; fidelity packages use `dist/renderer-artifact-provenance.json` instead)

A failed structural check skips launch and returns status `prerequisite` (exit **2**), not a runtime fail.

### Entrypoint graph

`verifyEntrypointGraph` treats each `PRODUCTION_ENTRYPOINTS` role as **clean-source**. It fails as `opaque bundle fallback` when the artifact:

- lacks provenance for the expected `source/` or `frontend/src/` entry
- is byte-identical to `src/app/...`
- declares a non-`clean-source` composition mode
- imports `src/app`
- (renderer) does not prove **11/11** `reviewed` + `cleanComposition: "present"` route contracts

Default `npm run package` composition is `fidelityRuntimeComposition`: renderer `checksum-pinned-artifact-runtime`, Electron-main and host `artifact-fallback`. That package can pass `npm run verify` and still fail smoke’s entrypoint graph.

### Production launch constraints

`launchPackagedApp` only runs when the path ends in `.app` and structural checks passed.

<ParamField body="platform" type="string" required>
Must be `darwin`. Other platforms skip with `runtime:platform`.
</ParamField>

<ParamField body="applications location" type="path" required>
`realpath(app)` must be inside `/Applications`. Dist payloads fail `runtime:applications-location` with `native launch refused before the immutable move-to-Applications prompt`.
</ParamField>

<ParamField body="codesign" type="command" required>
`codesign --verify --deep --strict --verbose=2`. Unsigned bundles are a prerequisite, not a runtime fail.
</ParamField>

<ParamField body="mock keychain" type="bytes" required>
`Contents/Frameworks/Electron Framework.framework/Electron Framework` must contain the UTF-8 needle `use-mock-keychain`. Launch args are exactly `--use-mock-keychain`.
</ParamField>

### Isolated environment

`createNativeTestEnvironment` copies `process.env`, **deletes** the production denylist keys, then sets:

| Key | Value |
| --- | --- |
| `SAND_USER_DATA_DIR` | `mkdtemp(.../grok-bot-native-e2e-)` |
| `SAND_DATA_ROOT` | `<userData>/sand-data` |
| `SAND_DISABLE_UPDATES` | `"1"` (overwrite) |
| `SAND_DISABLE_TELEMETRY` | `"1"` |
| `SAND_DISABLE_ANALYTICS` | `"1"` |

Denylist keys (must be absent on the spawned env): `GROK_BOT_RECONSTRUCTED_DEV`, `ELECTRON_RUN_AS_NODE`, `VITE_DEV_SERVER_URL`, `SAND_DEV_LOGIN`, `SAND_DEV_LOGIN_EMAIL`, `SAND_BACKEND_URL`, `CURSOR_API_BASE_URL`, `NODE_PATH`, `NODE_OPTIONS`, `NODE_EXTRA_CA_CERTS`, `NODE_V8_COVERAGE`, `ELECTRON_LOG_FILE`, `ELECTRON_ENABLE_LOGGING`, `SAND_HOST_GATEWAY_URL`, `SAND_HOST_GATEWAY_TOKEN`, `SAND_HOST_GATEWAY_NETWORK_TOKEN`, `SAND_FEATURE_GATE_OVERRIDES`, `SAND_MODEL_EXPERIMENT_OVERRIDE`.

Poll interval is **250 ms**. After the window the process group gets `SIGTERM`, then `SIGKILL`, and the temp profile is deleted.

### Fresh-profile pass criteria

`classifyFreshProfileRuntimeEvidence` **requires** a renderer descendant and **requires host and coordinator to stay absent** for a fresh profile. `runtime:daemon-observation` always passes (presence is recorded, not gated).

Fatal log patterns include uncaught exception, unhandled rejection, fatal error, segmentation fault, renderer crash, failed-to-load entry, `cannot find module`, `syntaxerror:`. Opaque-fallback patterns include `opaque bundle fallback`, shipped/legacy bundle fallback, `src/app` loading, and `GROK_BOT_ALLOW_OPAQUE_FALLBACK`.

### Observation report

Reports are `schemaVersion: 1`, `reportKind: "native-observation"`, `producer: "native-e2e"`.

| `observationClass` | When |
| --- | --- |
| `deterministic-prerequisite-no-launch` | missing payload, failed structural graph, or launch prerequisites |
| `admissible-production-startup-observation` | launch ran |
| `structural-only` | `--structural-only` or non-`.app` payload |

`--json` prints the full report. Text mode prints `Native E2E verification: STATUS` (or smoke’s `Smoke verification:` line).

## Updater guard

`reconstructedUpdaterGuard` in `scripts/lib/build-asar.mjs` is prepended to Electron-main artifact fallbacks by `prepareReconstructedElectronMainArtifactFallback` (also enables reconstructed instance/dev seams when `GROK_BOT_BUILD_DEV_APP=1`). `applyReconstructedUpdaterGuard` is idempotent: a source that already starts with the guard is left unchanged.

```js
// Reconstructed-build guard: do not consume official update or telemetry services.
process.env.SAND_DISABLE_UPDATES ??= "1";
process.env.SAND_DISABLE_SENTRY ??= "1";
process.env.SAND_DISABLE_TELEMETRY ??= "1";
```

`tests/reconstructed-updater-guard.test.mjs` asserts those three `??= "1"` assignments, idempotence, and that fallback packaging still starts with the same guard.

<Warning>
The packaged guard uses nullish assignment (`??=`) so a caller can still force-enable a service. Smoke **overwrites** `SAND_DISABLE_UPDATES` and `SAND_DISABLE_TELEMETRY` to `"1"` and also sets `SAND_DISABLE_ANALYTICS` (not part of the packaged guard). The packaged guard sets `SAND_DISABLE_SENTRY`; smoke does not.
</Warning>

## Exit codes

| Code | `verify` | `smoke` / `native-e2e-check` |
| --- | --- | --- |
| `0` | all checks passed | `report.status === "pass"` |
| `1` | uncaught `Error` (Node default) | `fail` |
| `2` | not used | `prerequisite` (do not treat as a product crash) |

## Operator procedure

<Steps>
<Step title="Package on Darwin">
Run `npm run package` so `dist/Grok Bot 0.18 Reconstructed.app` exists, is ad-hoc signed, and uses reconstructed identity. Packaging already runs `codesign --verify --deep --strict` and `verifyReconstructedMacPackage`.
</Step>
<Step title="Verify the dist app">
Run `npm run verify`. Confirm the log names the ASAR, clean-source count, non-clean boundaries (`electron-main`, `host`, `renderer` on the default fidelity package), and evidence-marker count ≥ 1000.
</Step>
<Step title="Optional: install then observe startup">
Copy the signed app into `/Applications`. Run `node scripts/native-e2e-check.mjs --app /Applications/Grok Bot 0.18 Reconstructed.app --timeout-ms 12000`. Expect `prerequisite` unless the payload also satisfies smoke’s clean-source entrypoint graph (not the default checksum-pinned renderer).
</Step>
</Steps>

## Failures

<AccordionGroup>
<Accordion title="ASAR is missing /dist/...">
The packaged archive listing does not contain a required runtime, renderer index, or composition JSON. Re-run `npm run package`; do not hand-edit `app.asar`. See packaging failures for missing renderer patch anchors and unsigned replacements.
</Accordion>
<Accordion title="Expected at least 1,000 surviving evidence source markers">
`src/app/dist` is missing or not the hydrated 0.18 payload. Run bootstrap before package/verify.
</Accordion>
<Accordion title="Unexpected reconstructed bundle ID / display name">
`Info.plist` was not rewritten to `com.anysphere.sand.reconstructed` / `Grok Bot 0.18 Reconstructed`, or you pointed `--app` at the official reference app.
</Accordion>
<Accordion title="Stale ElectronAsarIntegrity metadata">
Packaging must `plutil -remove ElectronAsarIntegrity` after replacing `app.asar`. Remaining integrity metadata fails verify.
</Accordion>
<Accordion title="Smoke: Missing required packaged artifact dist/renderer/renderer-source-provenance.json">
Default fidelity packages ship `dist/renderer-artifact-provenance.json`. Smoke’s artifact list still requires the clean-source provenance filename. Exit 2 is expected for `npm run package` output.
</Accordion>
<Accordion title="Smoke: opaque bundle fallback">
Entrypoint graph rejected artifact-fallback main/host or checksum-pinned renderer. That is a stricter policy than `npm run verify`.
</Accordion>
<Accordion title="runtime:applications-location">
Launch is refused for anything whose realpath is not under `/Applications`, including `dist/*.app`.
</Accordion>
<Accordion title="runtime:keychain-isolation">
The bundled Electron Framework binary does not contain `use-mock-keychain`. Native launch is refused.
</Accordion>
<Accordion title="runtime:host or runtime:coordinator fail after launch">
Fresh-profile policy treats host or coordinator evidence as failure. Renderer must appear; host and coordinator must not.
</Accordion>
</AccordionGroup>

## Next

<CardGroup>
<Card title="Package the macOS app" href="/package-macos-app">
How `npm run package` compiles runtimes, replaces `app.asar`, sets reconstructed identity, and ad-hoc signs.
</Card>
<Card title="Packaging failures" href="/packaging-failures">
Non-darwin abort, missing renderer patch anchors, codesign retry, quarantine, and verify ASAR gaps.
</Card>
<Card title="npm scripts" href="/npm-scripts">
Exact `package.json` commands including `check`, `package`, `verify`, and `smoke`.
</Card>
<Card title="Environment variables" href="/environment-variables">
`GROK_BOT_OUTPUT_APP_NAME`, `SAND_DISABLE_*`, and related packaging overrides.
</Card>
<Card title="Reconstruction boundary" href="/reconstruction-boundary">
Why the default packaged renderer stays checksum-pinned while `source/` runtimes compile separately.
</Card>
<Card title="Contributing" href="/contributing">
Required `check` and `package`/`verify` gates; do not weaken checksum or signing checks.
</Card>
</CardGroup>
