From 93d9a439b431b7788d909ae9b6a5c25ea00f000d Mon Sep 17 00:00:00 2001 From: Ousama Ben Younes Date: Sun, 7 Jun 2026 08:54:38 +0000 Subject: [PATCH] fix(shrink): restore nested protected-segment sentinels (#444) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit withProtectedSegments built sentinels in a single pass and restored them in a single pass. When two PROTECTED_PATTERNS matched the same span (e.g. path rule swallows STARTER/BUSINESS, then function-call rule swallows the resulting type ( 0 )), the outer sentinel restored to "type ( 0 )" but the inner " 0 " was never substituted back — enum values reaching the model became literal "( 0 )". Restore now loops with MAX_RESTORE_PASSES bound; same depth is reached on the actual #444 inputs in <=2 passes. Co-Authored-By: Claude --- src/mcp-servers/caveman-shrink/compress.js | Bin 4379 -> 5061 bytes tests/test_mcp_shrink.js | 24 +++++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/src/mcp-servers/caveman-shrink/compress.js b/src/mcp-servers/caveman-shrink/compress.js index 6edbb99be59547db10c956da291a41b35b2d4142..8475227a49bd2e509bf29f8a13705072bf386290 100644 GIT binary patch delta 700 zcmZuuyN=U96kUXrBBG}~K!L4IoGntU2q}V;VhbROvl0c;X4bw*Mhr97%ymL|DEtF- zd;l%degi+kZ_seZW>etg+;MMM!XhbeZ-L929~8GA`~1LuyN*G1k^fp6eLU zmQ}%7w3|g{Awd~y9~azd-W-}NaYjiMZ+i0FiatW3t!kDzZwWs>e#R+uz)JZzlB1!r zdw5c&zjNM{t%3Y3+crZ}i!*MmC1Puqbqi;ux~G#D7xQVpcs{=~y_ik%e41m7)2nUg z=k0?y&wrP%rE+S|pu38EO4cT5F?^=m2i z!EiWCGa<`*2ifnYzA*+z$;g0GxMVo3C{%rQ { assert.deepEqual(opts.stdio, ['pipe', 'pipe', 'inherit']); }); +test('preserves enum values inside parens (nested sentinel restoration — #444)', () => { + // Path pattern matches "STARTER/BUSINESS" first (sentinel 0). + // Function-call pattern then matches "type ( 0 )" (sentinel 1). + // Single-pass restore replaces " 1 " with "type ( 0 )" but leaves the + // inner " 0 " unrestored — model sees "( 0 )" instead of the enum. + const cases = [ + { in: 'plan type (STARTER/BUSINESS)', needle: 'STARTER/BUSINESS' }, + { in: 'user role (ADMIN/MEMBER/GUEST)', needle: 'ADMIN/MEMBER/GUEST' }, + { in: 'user plan (Free/Pro/Business)', needle: 'Free/Pro/Business' }, + ]; + for (const c of cases) { + const { compressed } = compress(c.in); + assert.ok( + compressed.includes(c.needle), + `nested sentinel leaked: expected "${c.needle}" in output, got "${compressed}"` + ); + assert.doesNotMatch( + compressed, + / \d+ /, + `unrestored sentinel " N " left in output: "${compressed}"` + ); + } +}); + console.log(`\n${passed} passed, ${failed} failed`); process.exit(failed ? 1 : 0);