Repository navigation
feat(account): complete guarded change feed adoption - #2910
Conversation
There was a problem hiding this comment.
Ladon verdict: Approve
Approve — AdCP 3.2 account change feed (drain stream, webhook parser, subscription builder, branded cursor types, storyboard-runner support, migration guide).
No blocking findings. The reviewer verified the acknowledgement/checkpoint state machine, fail-closed drain error handling with bounded reboot, witness-preserving normalization, seller-key sanitization in error paths, JSON hardening, branded cursor type safety, and a correctly-sized minor changeset. No Critical/High/Medium findings were surfaced.
Decision trace:
- No no-auto-approve team match (HARD RULE not triggered).
- gated_paths: false → row 2 does not fire despite review_decision REVIEW_REQUIRED.
- high_risk: false → rows 3 and 5 do not fire.
- No findings of any severity → rows 1, 4, 8 do not fire.
- No prior decision → row 6 does not fire.
- Falls through to row 9 → approve.
There was a problem hiding this comment.
Ladon verdict: Approve
Approve — clean pass, no blocking or medium findings.
Checked:
- No critical/high/medium findings in this run.
- Author is not on any no-auto-approve team.
- gated_paths: false (row 2 not triggered).
- high_risk: false; no deleted/modified high-risk paths.
- Prior decision was
approve; this is a net-positive iteration adding defensive hardening on the untrustedaccount.change_recordedwebhook path plus a test.
Reviewer notes three defensive changes: removal of a dead item !== null guard in account-change-json.ts (null handled upstream), ReDoS hardening in equalInstant (anchored date regex, O(n) trailing-zero trim, cross-offset instant equality preserved) in account-change-recorded.ts, and an 8192-digit fractional-timestamp test covering identity-preservation and mismatch. Changeset is present and consistent with wire-impact rules.
No escalation triggers fired; falls through to row 9.
There was a problem hiding this comment.
Ladon verdict: Approve
Approve — delta pass on a prior clean approve.
The only change since the prior clean approve (head 7bd4d99) is scripts/check-package-size.mjs, where MAX_PACKED_FILE_COUNT is raised 5,995 → 6,016 (+21) to track exactly 21 new packed artifacts (five module sets × 4 + one migration guide). The arithmetic is exact, the bump is tight with no slack, byte budgets are untouched, and a changeset is present.
No critical/high/medium findings this run; no prior blockers to re-evaluate. No author team gate, gated_paths is false, high_risk is false. None of decision rows 1–8 fire → row 9 approve.
There was a problem hiding this comment.
Ladon verdict: Approve
Approve — clean subsequent pass, no blocking or medium findings.
This is a follow-up review on a two-file delta since the prior approve (head 7bd4d99). Changes verified:
docs/migration-account-change-feed.md: swaps a mutable PR ref for the pinned immutable SHAea5498db— correct doc-link hygiene.scripts/check-package-size.mjs: bumpsMAX_PACKED_FILE_COUNT5,995 → 6,016 (+21); arithmetic and comment verified.
No new findings this run, and the prior pass had no blockers to re-evaluate. Changeset present (.changeset/quiet-account-change-drain.md) covering the src/lib/** changes.
Gate checks: gated_paths is false, so row 2 does not apply despite review_decision: REVIEW_REQUIRED. No no-auto-approve team match. high_risk false. No critical/high/medium findings. None of rows 1–8 fire → row 9 approve.
Buyers can already call
listAccountChanges(), but need safe boundaries between a webhook wake-up, ordered invalidation ingestion, and an acknowledged durable checkpoint. Complete the adopter-facing remainder of #2669 using the existing generated protocol types, client method, notification enums, and runtime schemas.account.change_recordedparsing with typed errors, bounded JSON input, and logical/retry/account/subscriber/resource/action identity checks. Preserve valid unknown resource/action invalidations.CURSOR_EXPIRED.Uses merged adcontextprotocol/adcp#7516 for the bounded training-seller shared-creative/capability correction. The recipe pins immutable merge
ea5498db0c611ad5b8e95618f97334f9db59e973. Seller implementation stays upstream. Adopter storage, projection/checkpoint transactions, durable feed storage (#2681), and subscription runtime (#2848) remain outside this SDK change.Validation:
ci:quickcompleted its format/type/build/fast checks with one existing local-only test hitting Node's default 4 GB heap ceiling. All 14 tests in that file pass with an 8 GB heap. Remaining slow and workspace suites were run separately and pass.No generated adoption changes are duplicated from #2907, which was still open when this PR merged. The published rc.2 and rc.3 account-feed storyboard and schema contracts are equivalent apart from schema version IDs.
Fixes #2669