fix: close audit punch-list #44–#70#72
Merged
Merged
Conversation
Close out the audit punch-list from issues #44–#70 in a single batch so the SDK lands a coherent set of behavior + docs + tests rather than a sprawl of one-line PRs. Bugs - ARCPClient: multiplex the transport inbound flow through a SharedFlow so listJobs (and future correlated calls) cannot steal envelopes from concurrent receive() subscribers (#58). - CapabilityNegotiation: only reject on REQUIRED-feature mismatches and intersect binaryEncoding inside the advertised set; drop unknown vendor extensions silently (#51, #57). - ARCPRuntime: malformed messages now return a correlated Nack instead of ending the runtime loop (#47). Session challenge flow either drives to completion or rejects explicitly (#50). - EventLog: serialize all JDBC access through a Mutex so SQLite is not reentered from multiple coroutines (#48); idempotency now covers envelopes without a session id via a sentinel column value (#49). - JobInventory: opaque, sort-key-tied pagination cursors so concurrent record/updateStatus cannot skip or duplicate pages (#59); expose evict + size so callers can enforce a retention window (#60). - JwtAuth: honor allowedClockSkew on exp/nbf (default 1 minute) and optionally verify the issuer claim (#61). - AgentRegistry / ArtifactStore: drop unsafe mutable collections in favor of concurrent maps; ArtifactStore enforces size bounds and reports overflow rather than silently dropping (#52). - BudgetCounter / BudgetRegistry: counters never overshoot zero; the registry returns NotFound for unregistered jobs instead of masking configuration bugs (#65, #66). - ResultChunkAssembler: AssembledResult has content equality over its ByteArray payload (#53); avoid repeated decoding and byte boxing on the hot path (#54); class-level KDoc states the not-thread-safe contract (#67). - CredentialStore.revokeWithRetry: exponential backoff and a broader retryable-exception filter (#68). - DefaultUpstreamErrorTranslator: structured cause matching replaces substring sniffing and the synthetic "unknown" currency (#69). - Samples: remove the human-input sample that pointed at deleted source; init-time check rejects new entries with missing files (#55). Docs - Make README and getting-started quickstarts runnable end-to-end against the current API (#44). - Correct conformance docs that overclaimed runtime support (#45). - Add property-level KDoc across the public message models (#46). - Treat Metric.unit as non-nullable in docs (#63). - Fix docs/guides/job-events.md reference to JobStarted.jobId (#64). - Clarify Capabilities.interrupt = true is a deliberate SDK exception to RFC §7, not a docs contradiction (#62). Testing & build - Add direct unit tests for ARCPClient correlation, JwtAuth, BudgetRegistry, BudgetCounter overshoot rejection, UpstreamErrorTranslator, MemoryTransport, ResultChunkAssembler equality, and CapabilityNegotiation edge cases (#70). - Wire Kover aggregate verification across :lib and :tests with line and branch coverage floors that fail CI on regression (#56). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This was referenced May 24, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Closes the open audit punch-list issues #44–#70 in a single coherent batch
of behavior fixes, doc corrections, and tests. Each section below maps
back to its issue.
Bug fixes
ARCPClient.listJobsno longer steals envelopes from concurrentreceive()subscribers — the transport flow is fanned out through ashared mutex'd waiter map.
CapabilityNegotiationrejects only on required-featuremismatches and intersects
binaryEncodingwithin the advertised set;unknown vendor extensions are silently dropped.
Nackinstead ofending the runtime loop.
EventLogserializes JDBC access through aMutexandenforces idempotency for envelopes without a session id (sentinel
substitution sidesteps SQLite's NULL-distinct semantics).
InMemoryJobInventoryuses opaque, sort-key-tiedpagination cursors and exposes
evict+sizefor retention.JwtAuthhonorsallowedClockSkew(default 1m) andoptionally verifies
iss.collections for
ConcurrentHashMap-backed maps with proper bounds.BudgetCounternever overshoots zero andBudgetRegistryreturns
NotFoundfor unregistered jobs instead ofOk.AssembledResultgets content equality; theassembler avoids repeated decoding + byte boxing and documents that
it is not thread-safe.
CredentialStore.revokeWithRetryuses exponential backoffand a broader retryable-exception filter.
DefaultUpstreamErrorTranslatoruses structured causematching instead of substring sniffing and the bogus
unknowncurrency.
check that prevents announcing a sample whose source is gone.
Docs
Capabilities.interrupt = truedocumented as a deliberateSDK exception to RFC §7, not a contradiction.
Metric.unitis documented as non-nullable.docs/guides/job-events.mdno longer references the missingJobStarted.jobId.Tests + build
JwtAuthTest,ResultChunkAssemblerEqualityTest,BudgetCounterRejectedTest,BudgetRegistryTest,UpstreamErrorTranslatorTest,MemoryTransportTest,ListJobsFanOutTest, plus expandedCapabilityNegotiationTestandListJobsHandlerTest.:lib+:testswith line/branchcoverage floors that fail CI on regression.
Test plan
./gradlew :lib:ktlintCheck :cli:ktlintCheck :tests:ktlintCheck./gradlew :lib:detekt :cli:detekt :tests:detekt./gradlew :lib:test :tests:test(rerun-tasks; all green)./gradlew assemble