feat(exthttp): centralize extension index ETag via Revision/BumpRevision#158
Merged
Conversation
The extension index ETag was previously hand-rolled in every extension's main.go as a process-start timestamp, so index caching was per-extension boilerplate and only invalidated on restart. Provide Revision()/BumpRevision() and RegisterIndexHandler so the index ETag is an SDK guarantee that reflects registration state: seeded with a startup nonce and bumped whenever a kit registers or clears a describable element. The value stays an unquoted string so it round-trips through the agent's If-None-Match handling unchanged.
|
Claude finished @joshiste's task in 1m 56s —— View job Review completeTodo list
SummaryReviewed Correctness / concurrency
Compatibility
Tests
No issues found — no bugs, no security concerns, no race conditions, and no typos affecting correctness. The change is small, self-contained, and consistent with the stated goal of centralizing the index ETag/revision logic in the SDK. |
This was referenced Jul 10, 2026
…andler The function registers a handler tagged with the current revision as its ETag; it has no notion of an index. Name it for that responsibility instead of one use site.
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 subscribe to this conversation on GitHub.
Already have an account?
Sign in.
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.
What
Adds
exthttp.Revision(),exthttp.BumpRevision(), andexthttp.RegisterRevisionedHandlerso the extension index ETag becomes an SDK guarantee instead of per-extensionmain.goboilerplate.Revision()— current revision string. Seeded at package init with a startup nonce (time.Now().UnixNano(), base36) so it differs across restarts, plus an atomic counter.BumpRevision()— advances the revision; kit SDKs call this from theirRegister*/Clear*functions.RegisterRevisionedHandler[T](path, getter)— registers a handler that serves the getter's result tagged withRevision()as its ETag (conditional GET → 304 on matchingIf-None-Match), replacing the hand-rolledstartedAt+IfNoneMatchHandlerwiring.Why
Previously each extension froze a
startedAttimestamp at process start and wrapped/withIfNoneMatchHandler. That made index caching copy-pasted boilerplate (an extension that forgot the wrapper silently lost caching) and boot-scoped rather than registration-scoped. The revision reflects the registered description set, so the agent's index-response cache invalidates on registration changes without needing a restart.Compatibility
The ETag value stays an unquoted string, byte-identical to the historical
startedAt, so it round-trips through the agent'sIf-None-Match/ETaghandling unchanged — no agent-side coordination required.IfNoneMatchHandleris unchanged and stays public for back-compat.Follow-ups
The
*-kitSDKs (action/discovery/advice/preflight) will bump this dependency and addBumpRevision()calls once this is tagged; extensions then swap their boilerplate toRegisterRevisionedHandler.