Claude: changes for issue #36 #64
No reviewers
Labels
No labels
breaking-change
bug
documentation
duplicate
enhancement
good first issue
help wanted
performance
question
wontfix
No milestone
No project
No assignees
2 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
Grandiras/ATProto.NET!64
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "claude/issue-36"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Closes #36.
🤖 Reviewing this PR — follow along in the action run; the reply will link the full session transcript.
📜 Live transcript — updating every ~5 minutes while the task runs.
Solid, well-scoped fix for issue #36 (closed registration was previously bypassable with any non-empty string). The three-step claim/confirm/release protocol correctly prevents double-spending under concurrency (verified by the
TryClaimAsync_ConcurrentClaims_NeverExceedsAvailableUsesandCreateAccountAsync_ConcurrentRedemptions_DoNotDoubleSpendACodetests), the failure-releases-the-claim path is tested, admin endpoints fail closed whenAdminPasswordis unset, and the password comparison usesFixedTimeEquals. CHANGELOG is thorough and correctly flags the binary-breaking constructor change and the behavioral change for closed-registration deployments. Test coverage across the store, service, and HTTP endpoint layers is extensive. No blocking correctness or security issues found; a couple of minor, non-blocking observations below.src/ATProtoNet.Pds/PdsHostingExtensions.cs:545— The admin username is compared withstring.Equals(..., StringComparison.Ordinal)rather than a constant-time comparison, while the password usesFixedTimeEquals. This is standard practice (usernames aren't normally treated as secret) and fine for the default"admin", but worth noting if a deployment ever treats a customAdminUsernameas sensitive.src/ATProtoNet.Pds/PdsService.cs:328—CreateInviteCodesAsyncissues codes per-account sequentially with no transactional rollback: if code creation fails partway through the account list (e.g. a store error on the second account), earlier accounts keep their already-created codes while the caller sees an exception with no indication of the partial state. Likely acceptable for this store's semantics, but worth a doc note since it's not obvious from the signature.⏱ 1m 5s · 1 turns · tokens: 45.6k in / 5.7k out (+29.1k cache-read)
📜 Full session transcript
@claude-bot Please fix the conflicts and work on the feedback.
🤖 On it — follow along in the action run; the reply will link the full session transcript.
📜 Live transcript — updating every ~5 minutes while the task runs.
Pushed to
claude/issue-36(commitc134a87) — conflicts resolved and both review points addressed.Conflicts
mainhad moved a long way underneath this branch (federation from #40, EF Core PDS stores from #38), so four files conflicted:PdsService.cs— both constructors now keep main's federation parameters and gain a trailing optionalIInviteCodeStore? inviteCodes = null.CreateAccountAsyncclaims the invite code up front, then mints the identity throughPdsIdentityServiceinside the try block, so a failed identity mint or account write releases the claim just like a taken handle does.PdsHostingExtensions.cs— a real collision, not just textual: main addedAddAtProtoPds<TAccountStore, TRepoStore, TCommitStore>(), which has the same arity as this branch'sAddAtProtoPds<TAccountStore, TRepoStore, TInviteCodeStore>(). Generic constraints don't disambiguate overloads, so the two could not coexist (CS0111). I replaced the invite-code overload withAddAtProtoPdsInviteCodeStore<TInviteCodeStore>(), matching theAddAtProtoPdsEfCoreStores<TContext>()pattern main established, and the in-memory default is now registered withTryAddso a host store wins in either call order.CreatePdsServicepasses the resolved store through.CHANGELOG.md/docs/pds.md— both sides' entries kept; the Invite Codes doc section moved to sit after the Configuration section rather than swallowing### Session signing keyas a subsection.Review feedback
PdsHostingExtensions.cs:918) — both halves of the Basic credential now go through fixed-time comparison, joined with non-short-circuiting&, so response time reveals neither which half failed nor how much of it matched. Length is still not hidden —FixedTimeEqualsreturns early on unequal spans — and that's stated in the doc comment.CreateInviteCodesAsyncpartial state (PdsService.cs:406) — documented as non-atomic in XML docs,docs/pds.md, and the CHANGELOG, with the recovery path spelled out (GetAccountInviteCodesAsync+DisableInviteCodesAsync, not a blind retry).useCountis now validated up front alongsidecodeCount, so a bad argument can no longer leave one account's batch written and the rest not — a store error is the only remaining partial-failure path.Verified
dotnet buildclean (0 errors), anddotnet test tests/ATProtoNet.Tests/passes 1394/1394 in both Debug and Release (CI runs Release). Three new tests: the invite store registration winning in either call order and actually being the onePdsServicewrites to,useCount: 0issuing nothing across a multi-account batch, and redemption recorded against a DID minted by a federating PDS — the path the merge newly created.⏱ 10m 6s · 78 turns · tokens: 106.1k in / 33.9k out (+6246.0k cache-read)
📜 Full session transcript