Skip to content

fix(agent,ai): eliminate the managed snapshot failure producers (root cause for #4578) - #4587

Merged
Yeachan-Heo merged 2 commits into
devfrom
fix/managed-snapshot-looping
Aug 15, 2026
Merged

fix(agent,ai): eliminate the managed snapshot failure producers (root cause for #4578)#4587
Yeachan-Heo merged 2 commits into
devfrom
fix/managed-snapshot-looping

Conversation

@Yeachan-Heo

@Yeachan-Heo Yeachan-Heo commented Aug 15, 2026

Copy link
Copy Markdown
Owner

gajae.pr-review-verdict.v1 merge-approved sha256:c2647d5f8c5f5ab1dffa3d4f066a9cf534f977c25d299d66b59d16055e0176d3 reviewer:human reviewer-id:probepark evidence:#4587 (review)

fix(agent,ai): eliminate managed snapshot failure producers

#4580 made residual local snapshot failures surface once instead of retrying. This PR removes the benign producers that trip that circuit breaker without duplicating or relaxing its retry policy.

Root causes fixed

Payload-class and readable-proxy roots (packages/agent)

Provider message/event classes can carry role, type, and payload fields on prototype getters. Live guards see those fields, but structuredClone copies only own enumerable properties, so the detached snapshot loses its identity. Managed assistant shell/event reconstruction now re-reads only known fields through the existing guarded managedProperty path when the detached root loses its discriminant. The run-loop message_update replay normalizes through managedAssistantEventSnapshot instead of spreading prototype-backed events.

Readable proxies whose descriptor trap is hostile are repaired through guarded gets. Unreadable get traps, throwing role getters, malformed non-string event types, and sanitizer-degraded content keep named fail-fast local snapshot diagnostics and never gain managed retry authority.

Cursor protobuf argument leak (packages/ai)

Cursor native tool calls previously attached protobuf-es payloads directly as toolCall arguments. Bigints, $typeName markers, byte arrays, cycles, and non-data leaves could defeat JSON serialization in managed staging, JSONL persistence, and replay. The provider boundary now converts arguments to plain JSON-safe records: safe-range bigint to number, larger bigint to decimal string, bytes to base64, dates to ISO, markers stripped, cycles/functions/unreadable objects to null, with explicit shared node and depth limits.

Scope and overlap

Fresh exact-head verification

  • Focused aggregate: 815 pass / 0 fail across 62 files (packages/agent/test, Cursor AI suites, coding-agent fallback integration).
  • Agent, AI, and coding-agent package Biome + TypeScript checks: clean.
  • Workspace build: natives, coding-agent binary, and stats: clean.
  • Affected PR planner and complete selected plan: agent-loop 38/38, managed transaction 51/51, Cursor safety 6/6, AI check, CLI smoke, baseline+modern native builds, coding-agent build, stats build: clean.
  • Generated native declaration drift restored; verified worktree clean.
  • Live Cursor provider session was not exercised; the protobuf boundary is covered with direct native-block and adversarial conversion regressions.

Exact-head review is requested from @probepark, @HaD0Yun, and @IYENTeam. needs-human remains binding until one authorized non-author reviewer approves this exact head and product CI is terminal green. Earlier reviews and runs are stale by construction.


[repo owner's gaebal-gajae (clawdbot) 🦞]

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, add credits to your account and enable them for code reviews in your settings.

Yeachan-Heo and others added 2 commits August 15, 2026 11:45
…ad leak

The #4580 circuit breaker surfaced local snapshot failures once, but the
producers that trip the circuit were still live. Two root causes are fixed
so the circuit does not fire on benign payloads at all:

packages/agent: a payload class carrying assistant/message-event fields on
prototype getters clones into an empty record (structuredClone copies only
own enumerable properties), so the live role/type checks passed while the
detached snapshot lost the identity and deterministically failed as
shell.role / event.unknownType. The shell and event snapshots now repair
such roots (and readable proxies) through the existing guarded-read path,
and the run-loop message_update replay normalizes through the managed event
snapshot instead of a naive spread that dropped prototype-carried fields.

packages/ai: cursor native tool calls attached raw protobuf-es payloads
(bigint fields, $typeName markers, byte arrays) as toolCall arguments,
defeating JSON.stringify in snapshot staging, transcript persistence, and
replay. Arguments are now converted to plain JSON-safe data at the provider
boundary.

Lore-id: 61d94fea
Constraint: hostile shapes (throwing get traps, sentinel-degraded content, non-string event types) keep named fail-fast diagnostics with no retry authority
Constraint: repair reads stay guarded (managedProperty) so a hostile trap can only degrade a field to undefined
Rejected: widening the sanitizer to accept unserializable staged values | hides producer defects behind lossy placeholders
Rejected: repairing hostile get-trap proxies | unreadable roots must not gain retry authority
Confidence: high
Scope-risk: medium
Reversibility: clean
Tested: payload-class end-to-end managed run; descriptor-trap proxy repair; cursor protobuf argument conversion; full agent suite (811 pass)
Not-tested: live Cursor provider session
The initial producer-boundary conversion still walked oversized containers and could throw on deeply nested or unreadable payload objects. Stop traversal at explicit node/depth limits and contain hostile enumeration while preserving object-shaped tool arguments.

Lore-id: 92d31e6a

Constraint: native tool arguments must remain plain JSON-safe records

Rejected: rely on protobuf payloads always being shallow and readable | leaves the advertised total conversion vulnerable to malformed provider data

Confidence: high

Scope-risk: low

Reversibility: clean

Tested: cursor native toolcall JSON safety suite
@Yeachan-Heo
Yeachan-Heo force-pushed the fix/managed-snapshot-looping branch from f380a78 to be83d77 Compare August 15, 2026 11:54
@Yeachan-Heo

Copy link
Copy Markdown
Owner Author

Signed exact-head reconstruction evidence

  • Reconstruction base: 804314081fe9d3f4d34014d1385f09d8d49a7116 (exact current dev, including merged fix(sdk): keep Windows OS probes and slow syncs off the session-index lock (#4544) #4555).
  • Preserved submitted head: f380a78ac8c129fb86846c62cde0887ed1db3c01 at preserve/pr-4587-submitted.
  • Published exact head: be83d77e46a8c92fdef1b6bb16f66b7969402d55.
  • Exact lease transition: f380a78ac8c129fb86846c62cde0887ed1db3c01 -> be83d77e46a8c92fdef1b6bb16f66b7969402d55 on existing branch fix/managed-snapshot-looping.
  • Canonical git diff --binary --full-index --no-ext-diff 80431408...be83d77e digest: sha256:c2647d5f8c5f5ab1dffa3d4f066a9cf534f977c25d299d66b59d16055e0176d3.
  • Scope is exactly six files: the submitted managed assistant shell/event producer repair, run-loop event normalization, Cursor protobuf argument conversion, changelogs, and focused regressions. The follow-up hardening stays inside the same Cursor conversion boundary and adds actual node/depth traversal limits plus unreadable-object containment.

Overlap audit:

Fresh exact-head verification:

  • Managed payload-class message/event roots, readable descriptor-trap proxies, unreadable get-trap/role-getter fail-fast behavior, non-string event types, terminal JSON serialization, and zero managed retry authority are covered by managed-attempt-transaction.test.ts.
  • Cursor safe-range/large bigint, bytes, $typeName, cycles/functions, native block serialization, unreadable payload objects, and bounded node/depth traversal are covered by cursor-native-toolcall-json-safety.test.ts.
  • Focused aggregate: 815 pass / 0 fail across 62 files (packages/agent/test, Cursor AI suites, and coding-agent fallback integration).
  • Package checks: agent, AI, and coding-agent Biome + TypeScript all clean.
  • Workspace build: natives, coding-agent binary, and stats build clean; generated native declaration drift restored.
  • Affected PR planner selected agent-loop 38/38, managed transaction 51/51, Cursor safety 6/6, AI check, CLI smoke, baseline+modern native builds, coding-agent build, and stats build. The complete selected plan passed.
  • Worktree is clean after verification.

Canonical verdict remains needs-human until an authorized non-author approval and exact-head product CI are both green. Exact-head review requests are active for @probepark, @HaD0Yun, and @IYENTeam. No prior approval or stale run authorizes this head.

Signed-by: Yeachan-Heo
Reviewed-head: be83d77


[repo owner's gaebal-gajae (clawdbot) 🦞]

@Yeachan-Heo

Copy link
Copy Markdown
Owner Author

Terminal exact-head CI classification

Authoritative Dev CI run: https://github.com/Yeachan-Heo/gajae-code/actions/runs/31883508312

Binding:

  • base: 804314081fe9d3f4d34014d1385f09d8d49a7116
  • head: be83d77e46a8c92fdef1b6bb16f66b7969402d55
  • digest: sha256:c2647d5f8c5f5ab1dffa3d4f066a9cf534f977c25d299d66b59d16055e0176d3

Product result: GREEN. State gates, affected plan, baseline+modern native build, CLI smoke, agent loop 38/38, managed transaction 51/51, Cursor safety 6/6, AI package check, coding-agent/stats builds, affected evidence/aggregate, and virtual integration all completed successfully. Platform-specific unrelated jobs were correctly skipped.

The sole failure is PR contract bootstrap, which reports Verdict needs-human intentionally blocks merge. This is the designed independent-review hold, not a product failure. Exact-head approvals remain 0; requested write-authorized reviewers are @probepark, @HaD0Yun, and @IYENTeam. No merge authorization exists until one approves this exact SHA and the body verdict is promoted with that reviewer identity.

Earlier runs 31883236903 and 31883272462 were superseded/cancelled by required PR-body contract updates and are not merge evidence.

Signed-by: Yeachan-Heo
Reviewed-head: be83d77


[repo owner's gaebal-gajae (clawdbot) 🦞]

@Yeachan-Heo

Copy link
Copy Markdown
Owner Author

OWNER_CONFIRMATION_REQUIRED — exact-head review is the only remaining gate

Current immutable review binding:

Bounded review surface: six files only — managed assistant shell/event root repair and regression, Cursor native toolCall JSON-safety boundary and regression, plus the two package changelog entries. Please verify that benign payload-class/readable-proxy roots are repaired, unreadable roots retain fail-fast/no-retry behavior, Cursor bigint/bytes/type markers/cycles stay JSON-safe and bounded, and #4580's circuit breaker is not duplicated or weakened.

Exact-head approvals are currently zero. Existing review requests remain active for write-authorized non-authors @probepark, @HaD0Yun, and @IYENTeam; this comment is the single refreshed notification and will not be repeated absent a head change. An APPROVED review must be submitted against the exact head above. On that approval, the sole verdict line can be promoted atomically with the same digest and reviewer/evidence binding, followed by the replacement bootstrap and immediate squash merge if all checks are green.

No self-approval or stale-head review will be used.


[repo owner's gaebal-gajae (clawdbot) 🦞]

@probepark probepark left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Approve at be83d77e4

fix(agent,ai): eliminate the managed snapshot failure producer, head commit "bound cursor payload
conversion". 6 files, +339.

Differential

# base 804314081, with this head's test files applied
(fail) managed snapshot benign degradation (PR #4538 salvage) > repairs payload-class messages and events whose fields live on the prototype
(fail) managed snapshot benign degradation (PR #4538 salvage) > repairs descriptor-trap proxy events whose guarded gets stay readable
SyntaxError: Export named 'buildNativeToolCallBlock' not found in module '.../providers/cursor.ts'
 49 pass  3 fail

# head be83d77e4
 57 pass  0 fail

It attacks the producer rather than the symptom

The previous rounds in this area treated managed snapshot failures as something to classify
(#4550's named sites), then to surface immediately rather than retry (#4580). This one removes the
cause: payload objects whose fields live on the prototype, and descriptor-trap proxies whose gets
are still readable, are now repaired at conversion time instead of rejected downstream.

That ordering is right. Naming and routing a failure is worth doing while the failure is
unavoidable; once the producer can be fixed, the classification machinery should have less to do,
not more.

bound cursor payload conversion in the same PR is the necessary guard - repairing prototype-backed
and proxied payloads means walking structures you did not construct, so it needs an explicit bound
rather than trusting the shape.

The two base failures are prototype-field and descriptor-trap repair specifically, so the tests
target the new capability rather than the surrounding plumbing.

merge-approved.

Reviewed by @probepark - method: fresh-worktree run at the exact head, separate clean base worktree with the head's test files to prove the differential.

@Yeachan-Heo
Yeachan-Heo merged commit 1e3e781 into dev Aug 15, 2026
69 of 83 checks passed
@Yeachan-Heo

Copy link
Copy Markdown
Owner Author

Signed terminal merge evidence and reproducible receipt

PR #4587 is terminally merged.

Approval and merge authority

Squash merge and concurrent-dev audit

Post-merge verification

  • Dedicated worktree and fetched origin/dev both resolve to 1e3e781b0f21faed4eb7ac7fba286816eac622c4.
  • bun run build passed on the merge commit: native addon, coding-agent binary, and stats build all completed successfully.
  • Generated native declaration drift was restored; tracked worktree is clean.
  • No release, tag, publish, main mutation, self-approval, or unrelated source mutation occurred.

Validated gajae receipt / reproducible record

gajae.merge-receipt.v1 valid sha256:4f5f44a17f47416141e843e11f2dc24e99ea4315285ca5c629035b07dba88e8f
repository=Yeachan-Heo/gajae-code pr=4587 target=dev method=squash
approvedBase=804314081fe9d3f4d34014d1385f09d8d49a7116
approvedHead=be83d77e46a8c92fdef1b6bb16f66b7969402d55
reviewer=probepark reviewId=4943899088 reviewState=APPROVED
replacementCi=31886474390 conclusion=success jobs=18-success/5-skipped/0-failed
mergeParent=9a97601ec11a878a829b37fb3c1f4c2cfd774dae
mergeCommit=1e3e781b0f21faed4eb7ac7fba286816eac622c4
diffSha256=c2647d5f8c5f5ab1dffa3d4f066a9cf534f977c25d299d66b59d16055e0176d3
postMergeBuild=passed linkedIssue4578=closed/completed

Reproduction: fetch dev; verify the approval review targets be83d77e...; verify run 31886474390 concludes success; hash git diff --binary --full-index --no-ext-diff 9a97601ec1...1e3e781b0f with SHA-256; verify origin/dev and PR merge_commit_sha equal 1e3e781b0f; run bun run build at that commit.

Signed-by: Yeachan-Heo
Merged-head: be83d77
Merge-commit: 1e3e781


[repo owner's gaebal-gajae (clawdbot) 🦞]

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.

2 participants