Skip to content

Expo plugin: no debugSymbolLevel (Gradle plugin 4.0.8 reads unstripped libraries); remove the old symbol block; bugsee-cli 0.7.12 - #64

Open
krassx wants to merge 3 commits into
chore/android-7.3.1-plugin-4.0.8from
feat/ndk-full-symbols
Open

krassx wants to merge 3 commits into
chore/android-7.3.1-plugin-4.0.8from
feat/ndk-full-symbols

Conversation

@krassx

@krassx krassx commented Oct 7, 2026 •

Copy link
Copy Markdown
Contributor

Reworked. This PR is stacked on #68 (Android SDK 7.3.1 and Gradle plugin 4.0.8), and its base is that branch; it moves to main when #68 merges. The earlier version (an ndkSymbolLevel option, FULL by default) is superseded: Bugsee Gradle plugin 4.0.8 uploads native symbols from the unstripped libraries in merged_native_libs, independent of ndk.debugSymbolLevel (gradle-plugin #10, PR #13; the 4.0.8 jar has useMergedNativeLibs/mergedNativeLibsDir and a CLI floor of 0.8.1). The old tip is kept as branch backup/ndk-full-symbols-633c2ae (local only).

Expo config plugin

  • Writes no debugSymbolLevel, on or off. debugSymbolLevel is the app's own choice for Google Play.
  • On every prebuild it removes the // bugsee-symbol-table: SYMBOL_TABLE block earlier versions wrote into debug/release. The block is recognised only by its marker plus its exact lines, at any indentation, with CRLF kept.
  • A level of the user's (code, dotted, defaultConfig, any build type) is never touched.
  • An old block the user changed inside is now the user's: it stays, and the prebuild log says so. It used to refuse with nativeCrashReporting: false.
  • Build-type anchors are gone, so a one-line release { … } or a closer that shares its line is no longer refused.
  • The unreleased ndkSymbolLevel option is dropped. The plugin never validated unknown options, so a config that still sets it prebuilds as if it were absent.
  • The block's text stays verbatim as the recognition fingerprint. Its claim that libreactnative.so is pre-stripped is false (the Maven AAR ships it with full DWARF), and that is noted at the constant.

Kept from the earlier version

Tests

  • Corpus: the generic oracle now forbids any Bugsee symbol-block line in the output, and requires the debugSymbolLevel count to equal the user's own across all 4 option sets, every ordered pair, and the chain. The anchor-refusal cases become kept-as-is cases. The changed-block cases stay as the user's. New cases: N01 (old blocks in debug and release beside a user FULL in defaultConfig), N02 (CRLF, beside the user's own ndk block), N03 (user levels in both build types), N04 (the block quoted in a string).
  • Unit: removal on and off, inside build types, partial markers, the changed-block note, the Expo SDK 57 template, and the old block plus a hand-written ndk block (equal to a fresh prebuild).
  • yarn lint, typecheck, test: 3335 tests, 12 skipped, all pass.
  • Focused Stryker (gradle.ts changed lines, --concurrency 3, under .mutation-lock): 18 of 19 killed. The survivor is the pre-existing equivalent ndkVersion !== null guard.

Real expo prebuild (examples/expo)

  • scripts/check-expo-prebuild.sh: ok (clean prebuild with no level; --no-clean changes nothing).
  • The old block hand-inserted into debug and release, then --no-clean: both removed, and the file is byte-identical to a fresh prebuild.
  • An old block changed inside ('FULL'), then --no-clean: kept byte-identical, and the log shows the note.

Native upload proof (in #68; loopback stub only)

A Release + R8 build of the bare example with no debugSymbolLevel: uploadBugseeReleaseNative ran bugsee-cli 0.8.1 on merged_native_libs/release and uploaded 64 libraries, each build-id equal to its stripped APK copy. libbugsee_e2e_native.so, libappmodules, libreactnative, libjsi and libfbjni went up as dwarf.

🤖 Generated with Claude Code

@cursor cursor Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale comment

Deep code review

Overall risk: Medium
Merge recommendation: Request changes

The plugin’s Groovy edits, option validation, in-place rewrite, and corpus coverage are careful. One --no-clean correctness bug remains: leftover Bugsee symbol blocks are rewritten to the configured level even when a user debugSymbolLevel already covers those types, so the effective AGP level disagrees with a clean prebuild and with the prebuild log.

I did not run the Jest plugin suite (no workspace node_modules). I did execute ensureAppAppliesPlugin from plugin/build/gradle.js against constructed --no-clean inputs.

Findings

  1. P2 — ensureSymbolLevel rewrites leftover own blocks before honoring a user covering setting (packages/react-native/plugin/src/gradle.ts). --clean / first run leaves defaultConfig (or an in-type user line) in charge; --no-clean after an earlier prebuild overlays FULL. Details in the inline comment.

Most important to fix

Detect user covering settings first. Where a user setting may apply, remove the plugin’s own block instead of rewriting it, so --no-clean matches --clean. Keep rewrite only for types with no user setting. Add a corpus case that combines a leftover debug/release block with defaultConfig (and one with a user line above the leftover inside debug).

Residual (not blocking)

  • Default full is a real size jump (~15 MB → ~140 MB native-debug-symbols.zip on the empty examples). Documented, with ndkSymbolLevel: "symbol_table" as the escape hatch.
  • A sibling staging { ndk.debugSymbolLevel … } or a dotted android.buildTypes.release.ndk… line is treated as covering debug and release (L07/L09). Conservative and documented; release can stay at AGP NONE.

Positive

Lexer-aware edits, refusal without echoing a bad option, line-for-line rewrite that keeps indent/CRLF, option-set × pair × chain corpus, bugsee-cli 0.7.12 so SYMBOL_TABLE .so.sym actually uploads, and the libreactnative.so comment now matches what Maven ships.

Open in Web View Automation 

Sent by Cursor Automation: Bugsee code review

Comment thread packages/react-native/plugin/src/gradle.ts Outdated
krassx added a commit that referenced this pull request Oct 7, 2026
Cursor review on #64: a block from an earlier prebuild was rewritten to
the configured level even where the user sets a level that covers that
build type. AGP overlays a build type's ndk.debugSymbolLevel on
defaultConfig, buildTypes.all and flavors, so on --no-clean the
leftover block overrode the user, while --clean honoured them.

The user's levels are now found on the file as given, before any
rewrite. Where one applies (anywhere outside debug/release: every
build type; inside one: that one), the plugin's complete blocks are
removed and none is inserted; elsewhere they are rewritten as before.
Only complete own blocks go, so a block the user changed is still
theirs and nothing refuses on this path. The log says the plugin keeps
no level of its own there.

Corpus: L26 (leftovers in both build types plus a defaultConfig level)
and L27 (a user line above a leftover block in debug); L24 now expects
the leftover beside the user's defaultConfig line to go.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

@cursor cursor Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale comment

Deep code review

Overall risk: Low
Merge recommendation: Approve

The prior --no-clean overlay is fixed. userSymbolLevelOffsets now runs on the file as given; complete own blocks in a covered span are dropped before rewrite; insert is skipped for those types. L26 (leftovers + defaultConfig) and L27 (user line above a leftover in debug) pin it. I reproduced both, and the original review fixture, against plugin/build/gradle.js.

No P0/P1. One residual P3 remains: drop is span-identity while insert is already by build-type name, so two debug { } (or release { }) closures in the same buildTypes can still disagree with --clean. Expo templates have one of each, so this is not the common upgrade path.

I did not run the Jest plugin suite (no workspace node_modules). I did execute ensureAppAppliesPlugin from plugin/build/gradle.js. GitHub expo prebuild (config plugin) is green on this head; lint/unit/mutation were still pending.

Findings

  1. P3 — covered tests the originating span, not the build-type name (packages/react-native/plugin/src/gradle.ts). Details in the inline comment.

Most important to fix

Use userNames in covered the same way insert already does, and add a corpus case with two debug { } closures (user level in the first, leftover in the second). Not blocking.

Residual (not blocking)

  • Default full is a real size jump (~15 MB → ~140 MB native-debug-symbols.zip on the empty examples). Documented, with ndkSymbolLevel: "symbol_table" as the escape hatch.
  • A sibling staging { ndk.debugSymbolLevel … } or a dotted android.buildTypes.release.ndk… line is treated as covering debug and release (L07/L09). Conservative and documented.

Positive

c5c3014 matches --clean for the leftover + defaultConfig / in-type cases the last review asked for. Lexer-aware edits, refusal without echoing a bad option, line-for-line rewrite that keeps indent/CRLF, option-set × pair × chain corpus, bugsee-cli 0.7.12 so SYMBOL_TABLE .so.sym actually uploads, and the libreactnative.so comment now matches what Maven ships.

Open in Web View Automation 

Sent by Cursor Automation: Bugsee code review

Comment thread packages/react-native/plugin/src/gradle.ts Outdated
krassx added a commit that referenced this pull request Oct 7, 2026
Cursor review on #64 (P3): the drop of leftover Bugsee blocks keyed on
the span holding the user's level, while insertion keyed on the build
type's name. AGP merges same-named closures in order, so with two
`debug { }` closures, the user's NONE in the first and a leftover block
in the second, --no-clean rewrote the leftover to FULL and it overlaid
the user's level. Both now use the name: a level in one closure covers
every closure of that build type. Corpus L28 is that file.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

@cursor cursor Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale comment

Deep code review

Overall risk: Low
Merge recommendation: Approve

Both prior leftover-overlay bugs are fixed on this head. Covering user levels are taken from the file as given; complete own blocks in a covered type are dropped before rewrite; drop and insert both key on the build-type name, so AGP’s last-wins merge of same-named closures cannot resurrect a leftover. L26, L27, and L28 pin it. I reproduced those, plus two release { } closures (leftover then user NONE) and leftovers beside a flavor / buildTypes.all level, against plugin/build/gradle.js: --no-clean matches --clean in each case.

No P0/P1/P2/P3.

Most important to fix

Nothing blocking.

Residual (not blocking)

  • Default full is a real size jump (~15 MB → ~140 MB native-debug-symbols.zip on the empty examples; ~95% is libreactnative.so.dbg). Documented, with ndkSymbolLevel: "symbol_table" as the escape hatch.
  • A sibling staging { ndk.debugSymbolLevel … } or a dotted android.buildTypes.release.ndk… line is treated as covering debug and release (L07/L09). Conservative and documented.
  • A user ndk { abiFilters … } inside a build type still skips insert, while a leftover own block in that type is rewritten. --clean then has no plugin level; --no-clean keeps FULL. Expo SDK templates have no such ndk block, and this is outside the covering-debugSymbolLevel contract the last two commits fixed.

Positive

Lexer-aware edits, refusal without echoing a bad option, line-for-line rewrite that keeps indent/CRLF, option-set × pair × chain corpus (L26–L28 included), bugsee-cli 0.7.12 so SYMBOL_TABLE .so.sym actually uploads, and the libreactnative.so comment now matches what Maven ships.

I did not run the Jest plugin suite (no workspace node_modules). I did execute ensureAppAppliesPlugin from plugin/build/gradle.js. GitHub expo prebuild (config plugin) is green on this head; lint/unit/mutation were still pending.

Open in Web View Automation 

Sent by Cursor Automation: Bugsee code review

@krassx
krassx force-pushed the feat/ndk-full-symbols branch from 633c2ae to 849547e Compare October 9, 2026 12:15
@krassx krassx changed the title Expo plugin: NDK symbol level FULL by default, ndkSymbolLevel option; bugsee-cli 0.7.12 Expo plugin: no debugSymbolLevel (Gradle plugin 4.0.8 reads unstripped libraries); remove the old symbol block; bugsee-cli 0.7.12 Oct 9, 2026
@krassx
krassx changed the base branch from main to chore/android-7.3.1-plugin-4.0.8 October 9, 2026 12:15
@krassx
krassx force-pushed the feat/ndk-full-symbols branch from 849547e to ccbf46b Compare October 9, 2026 12:17

@cursor cursor Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale comment

Deep code review

Overall risk: Low
Merge recommendation: Approve

This is the rework stacked on #68 (Android SDK 7.3.1 / Gradle plugin 4.0.8): the Expo plugin no longer writes ndk.debugSymbolLevel, and it removes only the exact seven-line // bugsee-symbol-table: block earlier versions inserted. The unreleased ndkSymbolLevel / insert path is gone, so the leftover-overlay and span-identity bugs from the old tip cannot recur. I reviewed ensureAppAppliesPlugin, removeInsertedSymbolTable, the corpus oracle, the Expo SDK 57 template test, the README Native symbols section, check-expo-prebuild.sh, and the @bugsee/cli 0.7.12 pin — not the diff in isolation.

removeInsertedSymbolTable matches the marker as a real // comment, then requires the remaining lines byte-for-byte at that indent (CR stripped). Exact 7 → drop; 4–6 (comments intact, body edited) → keep and log CHANGED_SYMBOL_BLOCK_NOTE; 1–3 → drop only those comment lines. A user debugSymbolLevel, ndk { }, flavor, or defaultConfig line is never a target. Build-type anchors are unused, so a one-line release { … } or a closer that shares its line is no longer refused. The corpus oracle requires the output debugSymbolLevel count to equal the user’s, across all four option sets, every ordered pair, and the chain. N01–N04 pin leftovers beside defaultConfig FULL, CRLF, user levels in both types, and a quoted block.

I executed ensureAppAppliesPlugin from plugin/build/gradle.js for those cases plus changed-inside FULL, stray two-comment prefix, tab indent, two debug { } closures, a flavor FULL, nativeCrashReporting off→on (block does not come back), and a triple-quoted copy. All behaved as specified. I did not run the Jest plugin suite (no workspace node_modules). GitHub CI on this head was still pending when this review was written.

No P0 / P1 / P2 / P3.

Most important to fix

Nothing blocking.

Residual (not blocking)

  • After upgrade, Play’s native-debug-symbols.zip goes back to AGP’s default NONE unless the app sets debugSymbolLevel itself. Documented; Bugsee upload no longer depends on that level.
  • A Gradle-plugin CLI pin below 0.8.1 falls back to the zip (documented). The wrapper @bugsee/cli 0.7.12 is the source-map / dSYM path and is separate from the plugin’s 0.8.1 floor.

Positive

Dropping insert is the right 4.0.8 contract: one removal function, lexer-guarded, idempotent on --no-clean. Changed-inside no longer fails the prebuild. README Native symbols section matches the code, including the libreactnative.so DWARF correction and the old-block upgrade path.

Open in Web View Automation 

Sent by Cursor Automation: Bugsee code review

@cursor cursor Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale comment

Deep code review

Overall risk: Low
Merge recommendation: Approve

Re-review of a703022 (stacked on #68 / bcfd6c6). Production Gradle edits are unchanged from ccbf46b; this commit only adds mutation-gap tests. I reviewed ensureAppAppliesPlugin, removeInsertedSymbolTable, the corpus oracle, the Expo SDK 57 template test, README Native symbols, check-expo-prebuild.sh, and the @bugsee/cli 0.7.12 pin — not the diff in isolation. Prior leftover-overlay / span-identity threads are fully_addressed: the insert path is gone, so those bugs cannot recur.

removeInsertedSymbolTable matches the // bugsee-symbol-table: marker as a real // comment, then requires the remaining lines byte-for-byte at that indent (CR stripped). Exact 7 → drop; 4–6 (comments intact, body edited) → keep and log CHANGED_SYMBOL_BLOCK_NOTE; 1–3 → drop only those comment lines. A user debugSymbolLevel, ndk { }, flavor, or defaultConfig line is never a target. Build-type anchors are unused, so a one-line release { … } or a closer that shares its line is no longer refused. The corpus oracle requires the output debugSymbolLevel count to equal the user’s, across all four option sets, every ordered pair, and the chain. N01–N04 pin leftovers beside defaultConfig FULL, CRLF, user levels in both types, and a quoted block.

I executed ensureAppAppliesPlugin from plugin/build/gradle.js for those cases plus changed-inside FULL, stray two-comment prefix, tab indent, two debug { } closures, a flavor FULL, nativeCrashReporting off→on (block does not come back), a trailing comment on ndk {, a closer that shares its line, and a triple-quoted copy. All behaved as specified. I did not run the Jest plugin suite (no workspace node_modules). GitHub CI on a703022 was still pending; the previous head (ccbf46b, run 37929119513) failed plugin mutation at 96.62. a703022 is the kill for those survivors (USER_NDK_NOTE on the off path, own NDK on line 1, inner indent after top-level code, open-comment refusals, plugins{ spacing); author reports focused Stryker 44/44 on those ranges.

No P0 / P1 / P2 / P3.

Most important to fix

Nothing blocking.

Residual (not blocking)

  • After upgrade, Play’s native-debug-symbols.zip goes back to AGP’s default NONE unless the app sets debugSymbolLevel itself. Documented; Bugsee upload no longer depends on that level (Gradle plugin 4.0.8).
  • A gradlePluginVersion pin below 4.0.8 still gets the leftover block stripped and no replacement level, so that older plugin falls back to an empty zip. The option is honored as written; 4.0.8 is the baked default.
  • A Gradle-plugin CLI pin below 0.8.1 falls back to the zip (documented). The wrapper @bugsee/cli 0.7.12 is the source-map / dSYM path and is separate from the plugin’s 0.8.1 floor.

Positive

Dropping insert is the right 4.0.8 contract: one removal function, lexer-guarded, idempotent on --no-clean. Changed-inside no longer fails the prebuild. README Native symbols section matches the code, including the libreactnative.so DWARF correction and the old-block upgrade path. a703022 restores oracles the insert-path tests used to keep alive, without putting a debugSymbolLevel write back.

Open in Web View Automation 

Sent by Cursor Automation: Bugsee code review

@krassx
krassx force-pushed the chore/android-7.3.1-plugin-4.0.8 branch from bcfd6c6 to b4d99fa Compare October 9, 2026 13:33
krassx added 3 commits October 9, 2026 18:34
…ions wrote

Bugsee Gradle plugin 4.0.8 uploads native symbols from the unstripped
libraries in merged_native_libs, whatever ndk.debugSymbolLevel says, so
the level is the app's own choice for Google Play.

- ensureAppAppliesPlugin no longer inserts the SYMBOL_TABLE block into the
  debug and release build types, on or off. A one-line build type, or a
  closer that shares its line, is therefore no longer refused.
- On every prebuild the block earlier versions wrote is removed, recognised
  by its marker and exact lines only. A level of the user's is never
  touched. A block the user changed inside is now the user's: it stays,
  and the prebuild log says so (it used to refuse with nativeCrashReporting
  off).
- The block text stays verbatim as the recognition fingerprint; its claim
  that libreactnative.so is pre-stripped is false (the Maven AAR ships it
  with DWARF), noted at the constant.
- @bugsee/cli 0.7.11 -> 0.7.12 (bugsee/bugsee-cli#61).
- Corpus: the oracle now forbids any Bugsee symbol-block line in the output
  and requires the debugSymbolLevel count to equal the user's own; new
  cases N01-N04 (old blocks in debug and release beside a user FULL, CRLF,
  user levels in both build types, the block quoted in a string).

🤖 Generated with [Claude Code](https://claude.com/claude-code)
…'s unstripped libraries

- README: a Native symbols (Android) section. Gradle plugin 4.0.8 uploads
  from merged_native_libs with bugsee-cli 0.8.1+, independent of
  debugSymbolLevel, which is the app's own choice for Google Play;
  libreactnative.so ships with DWARF, so React Native's own C++ gets
  file:line; the old symbol-table block goes on the next prebuild, a
  changed one stays as the user's. The bare manual setup drops its ndk
  block, the build-type anchors and the symbol-block refusal leave the
  plugin-edits text, and the CLI notes (0.7.12 for the wrapper, 0.8.1 for
  a pinned Gradle plugin CLI, bugsee/bugsee-cli#61) are kept.
- check-expo-prebuild.sh: the generated app/build.gradle has no
  debugSymbolLevel.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
…osed

CI's merged plugin score fell to 96.62 (break 97) once the well-killed
symbol-block insertion code was removed. New tests close real gaps: the
user-NDK note on the off path, an own NDK line on line 1, the inner
indentation after earlier top-level code, the exact open-comment refusals
for the dependencies opener and the React plugin line, and plugins{ with
no or several spaces before the brace (or code before it). Focused Stryker
on those ranges: 44/44 killed.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
@krassx
krassx force-pushed the feat/ndk-full-symbols branch from a703022 to f47acb0 Compare October 9, 2026 13:34

@cursor cursor Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale comment

Deep code review

Overall risk: Low
Merge recommendation: Approve

Re-review of f47acb0 after the force-push onto #68 / b4d99fa (prior head a703022). Production Gradle edits still write no ndk.debugSymbolLevel and remove only the exact seven-line // bugsee-symbol-table: block earlier versions inserted. The unreleased ndkSymbolLevel / insert path is gone, so the leftover-overlay and span-identity bugs from the old tip cannot recur. Prior threads on those bugs are fully_addressed. f47acb0 is tests only (mutation-gap oracles after insert-path removal dropped the plugin score).

I reviewed ensureAppAppliesPlugin, removeInsertedSymbolTable, the corpus oracle, the Expo SDK 57 template test, README Native symbols, check-expo-prebuild.sh, and the @bugsee/cli 0.7.12 pin — not the diff in isolation.

removeInsertedSymbolTable matches the marker as a real // comment, then requires the remaining lines byte-for-byte at that indent (CR stripped). Exact 7 → drop; 4–6 (comments intact, body edited) → keep and log CHANGED_SYMBOL_BLOCK_NOTE; 1–3 → drop only those comment lines. A user debugSymbolLevel, ndk { }, flavor, or defaultConfig line is never a target. Build-type anchors are unused, so a one-line release { … } or a closer that shares its line is no longer refused. The corpus oracle requires the output debugSymbolLevel count to equal the user’s, across all four option sets, every ordered pair, and the chain. N01–N04 pin leftovers beside defaultConfig FULL, CRLF, user levels in both types, and a quoted block.

I executed ensureAppAppliesPlugin from plugin/build/gradle.js for those cases plus changed-inside FULL, quoted copies (""" / ''' / $/), stray two-comment prefix, tab indent, two debug { } closures, a flavor FULL, nativeCrashReporting off→on (block does not come back), a trailing comment on ndk {, a closer that shares its line, four comments then a user ndk block, code before the marker, a column-0 exact block, and a blank line inside the block. All behaved as specified. I did not run the Jest plugin suite (no workspace node_modules). GitHub CI on f47acb0 (run 37937811176) was still pending; the previous head (ccbf46b, run 37929119513) failed plugin mutation at 96.62. f47acb0 is the kill for those survivors (USER_NDK_NOTE on the off path, own NDK on line 1, inner indent after top-level code, open-comment refusals, plugins{ spacing); author reports focused Stryker 44/44 on those ranges.

No P0 / P1 / P2 / P3.

Most important to fix

Nothing blocking.

Residual (not blocking)

  • After upgrade, Play’s native-debug-symbols.zip goes back to AGP’s default NONE unless the app sets debugSymbolLevel itself. Documented; Bugsee upload no longer depends on that level (Gradle plugin 4.0.8).
  • A gradlePluginVersion pin below 4.0.8 still gets the leftover block stripped and no replacement level, so that older plugin falls back to an empty zip. The option is honored as written; 4.0.8 is the baked default.
  • A Gradle-plugin CLI pin below 0.8.1 falls back to the zip (documented). The wrapper @bugsee/cli 0.7.12 is the source-map / dSYM path and is separate from the plugin’s 0.8.1 floor.

Positive

Dropping insert is the right 4.0.8 contract: one removal function, lexer-guarded, idempotent on --no-clean. Changed-inside no longer fails the prebuild. README Native symbols section matches the code, including the libreactnative.so DWARF correction and the old-block upgrade path. f47acb0 restores oracles the insert-path tests used to keep alive, without putting a debugSymbolLevel write back.

Open in Web View Automation 

Sent by Cursor Automation: Bugsee code review

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Deep code review

Overall risk: Low
Merge recommendation: Approve

Re-review of f47acb0 (stacked on #68 / b4d99fa). Production Gradle edits write no ndk.debugSymbolLevel and remove only the exact seven-line // bugsee-symbol-table: block earlier versions inserted. The unreleased ndkSymbolLevel / insert path is gone, so the leftover-overlay and span-identity bugs from the old tip cannot recur. Prior threads on those bugs are fully_addressed. f47acb0 is tests only (mutation-gap oracles after insert-path removal dropped the plugin score).

I reviewed ensureAppAppliesPlugin, removeInsertedSymbolTable, the corpus oracle, the Expo SDK 57 template test, README Native symbols, check-expo-prebuild.sh, and the @bugsee/cli 0.7.12 pin — not the diff in isolation.

removeInsertedSymbolTable matches the marker as a real // comment, then requires the remaining lines byte-for-byte at that indent (CR stripped). Exact 7 → drop; 4–6 (comments intact, body edited) → keep and log CHANGED_SYMBOL_BLOCK_NOTE; 1–3 → drop only those comment lines. A user debugSymbolLevel, ndk { }, flavor, or defaultConfig line is never a target. Build-type anchors are unused, so a one-line release { … } or a closer that shares its line is no longer refused. The corpus oracle requires the output debugSymbolLevel count to equal the user’s, across all four option sets, every ordered pair, and the chain. N01–N04 pin leftovers beside defaultConfig FULL, CRLF, user levels in both types, and a quoted block.

I executed ensureAppAppliesPlugin from plugin/build/gradle.js for those cases plus changed-inside FULL, quoted copies (""" / ''' / $/), stray two-comment prefix, tab indent, two debug { } closures, a flavor FULL, nativeCrashReporting off→on (block does not come back), a trailing comment on ndk {, a closer that shares its line, four comments then a user ndk block, code before the marker, a column-0 exact block, a blank line inside the block, and a block-comment copy. All behaved as specified. I did not run the Jest plugin suite (no workspace node_modules). GitHub CI on f47acb0 (run 37937811176) is 47/47 SUCCESS. Plugin mutation 97.39 (break 97): 2570 mutants, killed 2166, timeout 110, survived 51, noCoverage 10, runtimeErrors 6, ignored 227. That clears the 96.62 / 69-survived failure on ccbf46b (run 37929119513).

No P0 / P1 / P2 / P3.

Most important to fix

Nothing blocking.

Residual (not blocking)

  • After upgrade, Play’s native-debug-symbols.zip goes back to AGP’s default NONE unless the app sets debugSymbolLevel itself. Documented; Bugsee upload no longer depends on that level (Gradle plugin 4.0.8).
  • A gradlePluginVersion pin below 4.0.8 still gets the leftover block stripped and no replacement level, so that older plugin falls back to an empty zip. The option is honored as written; 4.0.8 is the baked default.
  • A Gradle-plugin CLI pin below 0.8.1 falls back to the zip (documented). The wrapper @bugsee/cli 0.7.12 is the source-map / dSYM path and is separate from the plugin’s 0.8.1 floor.

Positive

Dropping insert is the right 4.0.8 contract: one removal function, lexer-guarded, idempotent on --no-clean. Changed-inside no longer fails the prebuild. README Native symbols section matches the code, including the libreactnative.so DWARF correction and the old-block upgrade path. f47acb0 restores oracles the insert-path tests used to keep alive, without putting a debugSymbolLevel write back. CI mutation gate is green again.

Open in Web View Automation 

Sent by Cursor Automation: Bugsee code review

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