Repository navigation
Expo plugin: no debugSymbolLevel (Gradle plugin 4.0.8 reads unstripped libraries); remove the old symbol block; bugsee-cli 0.7.12 - #64
Conversation
There was a problem hiding this comment.
Stale comment
Deep code review
Overall risk: Medium
Merge recommendation: Request changesThe plugin’s Groovy edits, option validation, in-place rewrite, and corpus coverage are careful. One
--no-cleancorrectness bug remains: leftover Bugsee symbol blocks are rewritten to the configured level even when a userdebugSymbolLevelalready 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 executeensureAppAppliesPluginfromplugin/build/gradle.jsagainst constructed--no-cleaninputs.Findings
- P2 —
ensureSymbolLevelrewrites leftover own blocks before honoring a user covering setting (packages/react-native/plugin/src/gradle.ts).--clean/ first run leavesdefaultConfig(or an in-type user line) in charge;--no-cleanafter 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-cleanmatches--clean. Keep rewrite only for types with no user setting. Add a corpus case that combines a leftover debug/release block withdefaultConfig(and one with a user line above the leftover insidedebug).Residual (not blocking)
- Default
fullis a real size jump (~15 MB → ~140 MBnative-debug-symbols.zipon the empty examples). Documented, withndkSymbolLevel: "symbol_table"as the escape hatch.- A sibling
staging { ndk.debugSymbolLevel … }or a dottedandroid.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-cli0.7.12 soSYMBOL_TABLE.so.symactually uploads, and thelibreactnative.socomment now matches what Maven ships.Sent by Cursor Automation: Bugsee code review
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)
There was a problem hiding this comment.
Stale comment
Deep code review
Overall risk: Low
Merge recommendation: ApproveThe prior
--no-cleanoverlay is fixed.userSymbolLevelOffsetsnow 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 indebug) pin it. I reproduced both, and the original review fixture, againstplugin/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 { }(orrelease { }) closures in the samebuildTypescan 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 executeensureAppAppliesPluginfromplugin/build/gradle.js. GitHubexpo prebuild (config plugin)is green on this head; lint/unit/mutation were still pending.Findings
- P3 —
coveredtests 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
userNamesincoveredthe same way insert already does, and add a corpus case with twodebug { }closures (user level in the first, leftover in the second). Not blocking.Residual (not blocking)
- Default
fullis a real size jump (~15 MB → ~140 MBnative-debug-symbols.zipon the empty examples). Documented, withndkSymbolLevel: "symbol_table"as the escape hatch.- A sibling
staging { ndk.debugSymbolLevel … }or a dottedandroid.buildTypes.release.ndk…line is treated as covering debug and release (L07/L09). Conservative and documented.Positive
c5c3014 matches
--cleanfor 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-cli0.7.12 soSYMBOL_TABLE.so.symactually uploads, and thelibreactnative.socomment now matches what Maven ships.Sent by Cursor Automation: Bugsee code review
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)
There was a problem hiding this comment.
Stale comment
Deep code review
Overall risk: Low
Merge recommendation: ApproveBoth 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.alllevel, againstplugin/build/gradle.js:--no-cleanmatches--cleanin each case.No P0/P1/P2/P3.
Most important to fix
Nothing blocking.
Residual (not blocking)
- Default
fullis a real size jump (~15 MB → ~140 MBnative-debug-symbols.zipon the empty examples; ~95% islibreactnative.so.dbg). Documented, withndkSymbolLevel: "symbol_table"as the escape hatch.- A sibling
staging { ndk.debugSymbolLevel … }or a dottedandroid.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.--cleanthen has no plugin level;--no-cleankeeps FULL. Expo SDK templates have no suchndkblock, and this is outside the covering-debugSymbolLevelcontract 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-cli0.7.12 soSYMBOL_TABLE.so.symactually uploads, and thelibreactnative.socomment now matches what Maven ships.I did not run the Jest plugin suite (no workspace
node_modules). I did executeensureAppAppliesPluginfromplugin/build/gradle.js. GitHubexpo prebuild (config plugin)is green on this head; lint/unit/mutation were still pending.Sent by Cursor Automation: Bugsee code review
633c2ae to
849547e
Compare
849547e to
ccbf46b
Compare
There was a problem hiding this comment.
Stale comment
Deep code review
Overall risk: Low
Merge recommendation: ApproveThis 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 unreleasedndkSymbolLevel/ insert path is gone, so the leftover-overlay and span-identity bugs from the old tip cannot recur. I reviewedensureAppAppliesPlugin,removeInsertedSymbolTable, the corpus oracle, the Expo SDK 57 template test, the README Native symbols section,check-expo-prebuild.sh, and the@bugsee/cli0.7.12 pin — not the diff in isolation.
removeInsertedSymbolTablematches 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 logCHANGED_SYMBOL_BLOCK_NOTE; 1–3 → drop only those comment lines. A userdebugSymbolLevel,ndk { }, flavor, ordefaultConfigline is never a target. Build-type anchors are unused, so a one-linerelease { … }or a closer that shares its line is no longer refused. The corpus oracle requires the outputdebugSymbolLevelcount to equal the user’s, across all four option sets, every ordered pair, and the chain. N01–N04 pin leftovers besidedefaultConfigFULL, CRLF, user levels in both types, and a quoted block.I executed
ensureAppAppliesPluginfromplugin/build/gradle.jsfor those cases plus changed-inside FULL, stray two-comment prefix, tab indent, twodebug { }closures, a flavor FULL,nativeCrashReportingoff→on (block does not come back), and a triple-quoted copy. All behaved as specified. I did not run the Jest plugin suite (no workspacenode_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.zipgoes back to AGP’s defaultNONEunless the app setsdebugSymbolLevelitself. 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/cli0.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 thelibreactnative.soDWARF correction and the old-block upgrade path.Sent by Cursor Automation: Bugsee code review
There was a problem hiding this comment.
Stale comment
Deep code review
Overall risk: Low
Merge recommendation: ApproveRe-review of a703022 (stacked on #68 /
bcfd6c6). Production Gradle edits are unchanged from ccbf46b; this commit only adds mutation-gap tests. I reviewedensureAppAppliesPlugin,removeInsertedSymbolTable, the corpus oracle, the Expo SDK 57 template test, README Native symbols,check-expo-prebuild.sh, and the@bugsee/cli0.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.
removeInsertedSymbolTablematches 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 logCHANGED_SYMBOL_BLOCK_NOTE; 1–3 → drop only those comment lines. A userdebugSymbolLevel,ndk { }, flavor, ordefaultConfigline is never a target. Build-type anchors are unused, so a one-linerelease { … }or a closer that shares its line is no longer refused. The corpus oracle requires the outputdebugSymbolLevelcount to equal the user’s, across all four option sets, every ordered pair, and the chain. N01–N04 pin leftovers besidedefaultConfigFULL, CRLF, user levels in both types, and a quoted block.I executed
ensureAppAppliesPluginfromplugin/build/gradle.jsfor those cases plus changed-inside FULL, stray two-comment prefix, tab indent, twodebug { }closures, a flavor FULL,nativeCrashReportingoff→on (block does not come back), a trailing comment onndk {, a closer that shares its line, and a triple-quoted copy. All behaved as specified. I did not run the Jest plugin suite (no workspacenode_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.zipgoes back to AGP’s defaultNONEunless the app setsdebugSymbolLevelitself. Documented; Bugsee upload no longer depends on that level (Gradle plugin 4.0.8).- A
gradlePluginVersionpin 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/cli0.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 thelibreactnative.soDWARF correction and the old-block upgrade path. a703022 restores oracles the insert-path tests used to keep alive, without putting adebugSymbolLevelwrite back.Sent by Cursor Automation: Bugsee code review
bcfd6c6 to
b4d99fa
Compare
…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)
a703022 to
f47acb0
Compare
There was a problem hiding this comment.
Stale comment
Deep code review
Overall risk: Low
Merge recommendation: ApproveRe-review of f47acb0 after the force-push onto #68 /
b4d99fa(prior head a703022). Production Gradle edits still write nondk.debugSymbolLeveland remove only the exact seven-line// bugsee-symbol-table:block earlier versions inserted. The unreleasedndkSymbolLevel/ 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/cli0.7.12 pin — not the diff in isolation.
removeInsertedSymbolTablematches 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 logCHANGED_SYMBOL_BLOCK_NOTE; 1–3 → drop only those comment lines. A userdebugSymbolLevel,ndk { }, flavor, ordefaultConfigline is never a target. Build-type anchors are unused, so a one-linerelease { … }or a closer that shares its line is no longer refused. The corpus oracle requires the outputdebugSymbolLevelcount to equal the user’s, across all four option sets, every ordered pair, and the chain. N01–N04 pin leftovers besidedefaultConfigFULL, CRLF, user levels in both types, and a quoted block.I executed
ensureAppAppliesPluginfromplugin/build/gradle.jsfor those cases plus changed-inside FULL, quoted copies ("""/'''/$/), stray two-comment prefix, tab indent, twodebug { }closures, a flavor FULL,nativeCrashReportingoff→on (block does not come back), a trailing comment onndk {, 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 workspacenode_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.zipgoes back to AGP’s defaultNONEunless the app setsdebugSymbolLevelitself. Documented; Bugsee upload no longer depends on that level (Gradle plugin 4.0.8).- A
gradlePluginVersionpin 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/cli0.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 thelibreactnative.soDWARF correction and the old-block upgrade path. f47acb0 restores oracles the insert-path tests used to keep alive, without putting adebugSymbolLevelwrite back.Sent by Cursor Automation: Bugsee code review
There was a problem hiding this comment.
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.zipgoes back to AGP’s defaultNONEunless the app setsdebugSymbolLevelitself. Documented; Bugsee upload no longer depends on that level (Gradle plugin 4.0.8). - A
gradlePluginVersionpin 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/cli0.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.
Sent by Cursor Automation: Bugsee code review


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
mainwhen #68 merges. The earlier version (anndkSymbolLeveloption, FULL by default) is superseded: Bugsee Gradle plugin 4.0.8 uploads native symbols from the unstripped libraries inmerged_native_libs, independent ofndk.debugSymbolLevel(gradle-plugin #10, PR #13; the 4.0.8 jar hasuseMergedNativeLibs/mergedNativeLibsDirand a CLI floor of 0.8.1). The old tip is kept as branchbackup/ndk-full-symbols-633c2ae(local only).Expo config plugin
debugSymbolLevel, on or off.debugSymbolLevelis the app's own choice for Google Play.// bugsee-symbol-table:SYMBOL_TABLE block earlier versions wrote intodebug/release. The block is recognised only by its marker plus its exact lines, at any indentation, with CRLF kept.defaultConfig, any build type) is never touched.nativeCrashReporting: false.release { … }or a closer that shares its line is no longer refused.ndkSymbolLeveloption is dropped. The plugin never validated unknown options, so a config that still sets it prebuilds as if it were absent.libreactnative.sois pre-stripped is false (the Maven AAR ships it with full DWARF), and that is noted at the constant.Kept from the earlier version
@bugsee/cli0.7.11 → 0.7.12 (debug-files upload --type elf ignores .so.sym entries (AGP SYMBOL_TABLE): NDK symbols silently not uploaded bugsee-cli#61).libreactnative.socorrection, now in the README's new Native symbols (Android) section. That section covers the unstripped upload, DWARF for your own code and React Native's, symbol tables for stripped libraries, the server-side upgrade of a function-names-only copy,debugSymbolLevelas the app's Play choice, removal of the old block, and the CLI ≥0.8.1 note for a pinned Gradle-plugin CLI.scripts/check-expo-prebuild.shnow expects nodebugSymbolLevelin the generatedapp/build.gradle.Tests
debugSymbolLevelcount 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 indefaultConfig), N02 (CRLF, beside the user's own ndk block), N03 (user levels in both build types), N04 (the block quoted in a string).yarn lint,typecheck,test: 3335 tests, 12 skipped, all pass.gradle.tschanged lines,--concurrency 3, under.mutation-lock): 18 of 19 killed. The survivor is the pre-existing equivalentndkVersion !== nullguard.Real
expo prebuild(examples/expo)scripts/check-expo-prebuild.sh: ok (clean prebuild with no level;--no-cleanchanges nothing).--no-clean: both removed, and the file is byte-identical to a fresh prebuild.'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:uploadBugseeReleaseNativeran bugsee-cli 0.8.1 onmerged_native_libs/releaseand uploaded 64 libraries, each build-id equal to its stripped APK copy.libbugsee_e2e_native.so,libappmodules,libreactnative,libjsiandlibfbjniwent up asdwarf.🤖 Generated with Claude Code