Skip to content

rfc(decision): scope model RFC for Go - #156

Open
giortzisg wants to merge 7 commits into
mainfrom
rfc/scope-model-for-go
Open

rfc(decision): scope model RFC for Go#156
giortzisg wants to merge 7 commits into
mainfrom
rfc/scope-model-for-go

Conversation

@giortzisg

@giortzisggiortzisg commented Mar 19, 2026

Copy link
Copy Markdown

This RFC evaluates how sentry-go should model scope state so it can align with Sentry’s three-scope model

Rendered RFC

Links

@giortzisg
giortzisgforce-pushed the rfc/scope-model-for-go branch from 472b0ae to 2f73adfCompareMarch 19, 2026 11:24
@giortzisggiortzisg self-assigned this Mar 19, 2026
@giortzisg
giortzisg marked this pull request as ready for review March 19, 2026 11:25
@linear-code

Copy link
Copy Markdown

@sl0thentr0pysl0thentr0py left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

While I mostly understand the reasoning behind this RFC, and also partially agree with the arguments set forth, some considerations and comments:

Why 3 Scopes?

  • the whole point of the other 3 scope RFC was to make our scope more in line with otel copy-on-write context (which is the same design as go context) for POTEL (= bidirectional flow between sentry <-> otel)
  • if we already make our scope context like in this RFC suggests, we don't even need 3 scopes - just a global and a context-like scope suffices
  • the currentScope especially is really weird here because all it needs to hold is a span reference but we make it hold all the other stuff like tags and data and if we already have a copy-on-write structure we don't need the added complexity
  • honestly, since POTEL is now a dead project and we are already considering reverting it in JS, I'm not sure this whole 3-scope thing is even necessary. I'm definitely postpoining it and might not do it at all in Ruby, for instance.

Breaking Changes and Migration

We need a proper pathway for migration if we do this, so please add more clarification on this in the RFC.

Divergence

If we go forward with this in go, it will certainly create short term (if not permanent) divergence between go and other SDKs, something we have to be aware of and have buy-in from relevant people.


### Cons

- Major change from current SDK architecture, both for us and the users.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

we need concrete examples here on what migration would mean for the users and how much code they need to change

@giortzisg

Copy link
Copy Markdown
Author

The three scope model mapping section is mostly there for associating how the proposal would work when compared to the old approach.

I also agree that we don't really need the three scopes model (or at least limit it to only two scopes) for it to actually work, so let me rework the format a bit to be more clear.

@cleptric

Copy link
Copy Markdown
Member

As discussed offline, I'm in general happy with this approach, but we should include how a new span API interacts with the new scope model.

@giortzisg
giortzisg requested review from cleptric and sl0thentr0py and removed request for cleptricApril 7, 2026 10:25
Comment threadtext/0156-scope-model-for-go.md
Comment threadtext/0156-scope-model-for-go.md
Comment threadtext/0156-scope-model-for-go.md
#### Hub-in-context APIs

- SetHubOnContext(ctx, hub) and GetHubFromContext(ctx) stop being the primary user-facing propagation mechanism.
- Users should no longer manually clone hubs for request/task isolation, just pass the correct context.Context.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

this assumes that that go context forking semantics for concurrency/isolation are the same as what we were doing before. Does this hold for all cases where we manually forked before?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

That's a nice observation. I would say yes, since each scope.fork snapshot is essentially a different context. For forks that prevented mutability CoW guarantees that and for forks that are a snapshot of scope state, the mechanism now would be the ctx.

The only thing I can think of is CurrentHub.Clone() which becomes completely redundant under our model, since ctx and global scope would merge anyways on send.

Comment threadtext/0156-scope-model-for-go.md Outdated
#### Interaction with scope model

Under the proposed scope model, scope if only an infromation carrier and is no longer responsible for owning tracing state. The `context.Context` carries both the scope and active span state.
This means that `StartSpan` is also a scope-boundary operation and derived scopes already contain the previously inherited local state. Under this, the SDK does not need to merge separate scopes when a span ends. Semanticaly, the model gets simplified to:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

💯

Sign up for freeto 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.

5 participants

@giortzisg@cleptric@dingsdax@sl0thentr0py@lcian
, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
rfc(decision): scope model RFC for Go by giortzisg · Pull Request #156 · getsentry/rfcs · GitHub
Skip to content

rfc(decision): scope model RFC for Go - #156

Open
giortzisg wants to merge 7 commits into
mainfrom
rfc/scope-model-for-go
Open

rfc(decision): scope model RFC for Go#156
giortzisg wants to merge 7 commits into
mainfrom
rfc/scope-model-for-go

Conversation

@giortzisg

@giortzisggiortzisg commented Mar 19, 2026

Copy link
Copy Markdown

This RFC evaluates how sentry-go should model scope state so it can align with Sentry’s three-scope model

Rendered RFC

Links

@giortzisg
giortzisgforce-pushed the rfc/scope-model-for-go branch from 472b0ae to 2f73adfCompareMarch 19, 2026 11:24
@giortzisggiortzisg self-assigned this Mar 19, 2026
@giortzisg
giortzisg marked this pull request as ready for review March 19, 2026 11:25
@linear-code

Copy link
Copy Markdown

@sl0thentr0pysl0thentr0py left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

While I mostly understand the reasoning behind this RFC, and also partially agree with the arguments set forth, some considerations and comments:

Why 3 Scopes?

  • the whole point of the other 3 scope RFC was to make our scope more in line with otel copy-on-write context (which is the same design as go context) for POTEL (= bidirectional flow between sentry <-> otel)
  • if we already make our scope context like in this RFC suggests, we don't even need 3 scopes - just a global and a context-like scope suffices
  • the currentScope especially is really weird here because all it needs to hold is a span reference but we make it hold all the other stuff like tags and data and if we already have a copy-on-write structure we don't need the added complexity
  • honestly, since POTEL is now a dead project and we are already considering reverting it in JS, I'm not sure this whole 3-scope thing is even necessary. I'm definitely postpoining it and might not do it at all in Ruby, for instance.

Breaking Changes and Migration

We need a proper pathway for migration if we do this, so please add more clarification on this in the RFC.

Divergence

If we go forward with this in go, it will certainly create short term (if not permanent) divergence between go and other SDKs, something we have to be aware of and have buy-in from relevant people.


### Cons

- Major change from current SDK architecture, both for us and the users.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

we need concrete examples here on what migration would mean for the users and how much code they need to change

@giortzisg

Copy link
Copy Markdown
Author

The three scope model mapping section is mostly there for associating how the proposal would work when compared to the old approach.

I also agree that we don't really need the three scopes model (or at least limit it to only two scopes) for it to actually work, so let me rework the format a bit to be more clear.

@cleptric

Copy link
Copy Markdown
Member

As discussed offline, I'm in general happy with this approach, but we should include how a new span API interacts with the new scope model.

@giortzisg
giortzisg requested review from cleptric and sl0thentr0py and removed request for cleptricApril 7, 2026 10:25
Comment threadtext/0156-scope-model-for-go.md
Comment threadtext/0156-scope-model-for-go.md
Comment threadtext/0156-scope-model-for-go.md
#### Hub-in-context APIs

- SetHubOnContext(ctx, hub) and GetHubFromContext(ctx) stop being the primary user-facing propagation mechanism.
- Users should no longer manually clone hubs for request/task isolation, just pass the correct context.Context.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

this assumes that that go context forking semantics for concurrency/isolation are the same as what we were doing before. Does this hold for all cases where we manually forked before?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

That's a nice observation. I would say yes, since each scope.fork snapshot is essentially a different context. For forks that prevented mutability CoW guarantees that and for forks that are a snapshot of scope state, the mechanism now would be the ctx.

The only thing I can think of is CurrentHub.Clone() which becomes completely redundant under our model, since ctx and global scope would merge anyways on send.

Comment threadtext/0156-scope-model-for-go.md Outdated
#### Interaction with scope model

Under the proposed scope model, scope if only an infromation carrier and is no longer responsible for owning tracing state. The `context.Context` carries both the scope and active span state.
This means that `StartSpan` is also a scope-boundary operation and derived scopes already contain the previously inherited local state. Under this, the SDK does not need to merge separate scopes when a span ends. Semanticaly, the model gets simplified to:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

💯

Sign up for freeto 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.

5 participants

@giortzisg@cleptric@dingsdax@sl0thentr0py@lcian
, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' rfc(decision): scope model RFC for Go by giortzisg · Pull Request #156 · getsentry/rfcs · GitHub
Skip to content

rfc(decision): scope model RFC for Go - #156

Open
giortzisg wants to merge 7 commits into
mainfrom
rfc/scope-model-for-go
Open

rfc(decision): scope model RFC for Go#156
giortzisg wants to merge 7 commits into
mainfrom
rfc/scope-model-for-go

Conversation

@giortzisg

@giortzisggiortzisg commented Mar 19, 2026

Copy link
Copy Markdown

This RFC evaluates how sentry-go should model scope state so it can align with Sentry’s three-scope model

Rendered RFC

Links

@giortzisg
giortzisgforce-pushed the rfc/scope-model-for-go branch from 472b0ae to 2f73adfCompareMarch 19, 2026 11:24
@giortzisggiortzisg self-assigned this Mar 19, 2026
@giortzisg
giortzisg marked this pull request as ready for review March 19, 2026 11:25
@linear-code

Copy link
Copy Markdown

@sl0thentr0pysl0thentr0py left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

While I mostly understand the reasoning behind this RFC, and also partially agree with the arguments set forth, some considerations and comments:

Why 3 Scopes?

  • the whole point of the other 3 scope RFC was to make our scope more in line with otel copy-on-write context (which is the same design as go context) for POTEL (= bidirectional flow between sentry <-> otel)
  • if we already make our scope context like in this RFC suggests, we don't even need 3 scopes - just a global and a context-like scope suffices
  • the currentScope especially is really weird here because all it needs to hold is a span reference but we make it hold all the other stuff like tags and data and if we already have a copy-on-write structure we don't need the added complexity
  • honestly, since POTEL is now a dead project and we are already considering reverting it in JS, I'm not sure this whole 3-scope thing is even necessary. I'm definitely postpoining it and might not do it at all in Ruby, for instance.

Breaking Changes and Migration

We need a proper pathway for migration if we do this, so please add more clarification on this in the RFC.

Divergence

If we go forward with this in go, it will certainly create short term (if not permanent) divergence between go and other SDKs, something we have to be aware of and have buy-in from relevant people.


### Cons

- Major change from current SDK architecture, both for us and the users.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

we need concrete examples here on what migration would mean for the users and how much code they need to change

@giortzisg

Copy link
Copy Markdown
Author

The three scope model mapping section is mostly there for associating how the proposal would work when compared to the old approach.

I also agree that we don't really need the three scopes model (or at least limit it to only two scopes) for it to actually work, so let me rework the format a bit to be more clear.

@cleptric

Copy link
Copy Markdown
Member

As discussed offline, I'm in general happy with this approach, but we should include how a new span API interacts with the new scope model.

@giortzisg
giortzisg requested review from cleptric and sl0thentr0py and removed request for cleptricApril 7, 2026 10:25
Comment threadtext/0156-scope-model-for-go.md
Comment threadtext/0156-scope-model-for-go.md
Comment threadtext/0156-scope-model-for-go.md
#### Hub-in-context APIs

- SetHubOnContext(ctx, hub) and GetHubFromContext(ctx) stop being the primary user-facing propagation mechanism.
- Users should no longer manually clone hubs for request/task isolation, just pass the correct context.Context.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

this assumes that that go context forking semantics for concurrency/isolation are the same as what we were doing before. Does this hold for all cases where we manually forked before?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

That's a nice observation. I would say yes, since each scope.fork snapshot is essentially a different context. For forks that prevented mutability CoW guarantees that and for forks that are a snapshot of scope state, the mechanism now would be the ctx.

The only thing I can think of is CurrentHub.Clone() which becomes completely redundant under our model, since ctx and global scope would merge anyways on send.

Comment threadtext/0156-scope-model-for-go.md Outdated
#### Interaction with scope model

Under the proposed scope model, scope if only an infromation carrier and is no longer responsible for owning tracing state. The `context.Context` carries both the scope and active span state.
This means that `StartSpan` is also a scope-boundary operation and derived scopes already contain the previously inherited local state. Under this, the SDK does not need to merge separate scopes when a span ends. Semanticaly, the model gets simplified to:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

💯

Sign up for freeto 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.

5 participants

@giortzisg@cleptric@dingsdax@sl0thentr0py@lcian
, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' rfc(decision): scope model RFC for Go by giortzisg · Pull Request #156 · getsentry/rfcs · GitHub
Skip to content

rfc(decision): scope model RFC for Go - #156

Open
giortzisg wants to merge 7 commits into
mainfrom
rfc/scope-model-for-go
Open

rfc(decision): scope model RFC for Go#156
giortzisg wants to merge 7 commits into
mainfrom
rfc/scope-model-for-go

Conversation

@giortzisg

@giortzisggiortzisg commented Mar 19, 2026

Copy link
Copy Markdown

This RFC evaluates how sentry-go should model scope state so it can align with Sentry’s three-scope model

Rendered RFC

Links

@giortzisg
giortzisgforce-pushed the rfc/scope-model-for-go branch from 472b0ae to 2f73adfCompareMarch 19, 2026 11:24
@giortzisggiortzisg self-assigned this Mar 19, 2026
@giortzisg
giortzisg marked this pull request as ready for review March 19, 2026 11:25
@linear-code

Copy link
Copy Markdown

@sl0thentr0pysl0thentr0py left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

While I mostly understand the reasoning behind this RFC, and also partially agree with the arguments set forth, some considerations and comments:

Why 3 Scopes?

  • the whole point of the other 3 scope RFC was to make our scope more in line with otel copy-on-write context (which is the same design as go context) for POTEL (= bidirectional flow between sentry <-> otel)
  • if we already make our scope context like in this RFC suggests, we don't even need 3 scopes - just a global and a context-like scope suffices
  • the currentScope especially is really weird here because all it needs to hold is a span reference but we make it hold all the other stuff like tags and data and if we already have a copy-on-write structure we don't need the added complexity
  • honestly, since POTEL is now a dead project and we are already considering reverting it in JS, I'm not sure this whole 3-scope thing is even necessary. I'm definitely postpoining it and might not do it at all in Ruby, for instance.

Breaking Changes and Migration

We need a proper pathway for migration if we do this, so please add more clarification on this in the RFC.

Divergence

If we go forward with this in go, it will certainly create short term (if not permanent) divergence between go and other SDKs, something we have to be aware of and have buy-in from relevant people.


### Cons

- Major change from current SDK architecture, both for us and the users.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

we need concrete examples here on what migration would mean for the users and how much code they need to change

@giortzisg

Copy link
Copy Markdown
Author

The three scope model mapping section is mostly there for associating how the proposal would work when compared to the old approach.

I also agree that we don't really need the three scopes model (or at least limit it to only two scopes) for it to actually work, so let me rework the format a bit to be more clear.

@cleptric

Copy link
Copy Markdown
Member

As discussed offline, I'm in general happy with this approach, but we should include how a new span API interacts with the new scope model.

@giortzisg
giortzisg requested review from cleptric and sl0thentr0py and removed request for cleptricApril 7, 2026 10:25
Comment threadtext/0156-scope-model-for-go.md
Comment threadtext/0156-scope-model-for-go.md
Comment threadtext/0156-scope-model-for-go.md
#### Hub-in-context APIs

- SetHubOnContext(ctx, hub) and GetHubFromContext(ctx) stop being the primary user-facing propagation mechanism.
- Users should no longer manually clone hubs for request/task isolation, just pass the correct context.Context.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

this assumes that that go context forking semantics for concurrency/isolation are the same as what we were doing before. Does this hold for all cases where we manually forked before?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

That's a nice observation. I would say yes, since each scope.fork snapshot is essentially a different context. For forks that prevented mutability CoW guarantees that and for forks that are a snapshot of scope state, the mechanism now would be the ctx.

The only thing I can think of is CurrentHub.Clone() which becomes completely redundant under our model, since ctx and global scope would merge anyways on send.

Comment threadtext/0156-scope-model-for-go.md Outdated
#### Interaction with scope model

Under the proposed scope model, scope if only an infromation carrier and is no longer responsible for owning tracing state. The `context.Context` carries both the scope and active span state.
This means that `StartSpan` is also a scope-boundary operation and derived scopes already contain the previously inherited local state. Under this, the SDK does not need to merge separate scopes when a span ends. Semanticaly, the model gets simplified to:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

💯

Sign up for freeto 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.

5 participants

@giortzisg@cleptric@dingsdax@sl0thentr0py@lcian
, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' rfc(decision): scope model RFC for Go by giortzisg · Pull Request #156 · getsentry/rfcs · GitHub
Skip to content

rfc(decision): scope model RFC for Go - #156

Open
giortzisg wants to merge 7 commits into
mainfrom
rfc/scope-model-for-go
Open

rfc(decision): scope model RFC for Go#156
giortzisg wants to merge 7 commits into
mainfrom
rfc/scope-model-for-go

Conversation

@giortzisg

@giortzisggiortzisg commented Mar 19, 2026

Copy link
Copy Markdown

This RFC evaluates how sentry-go should model scope state so it can align with Sentry’s three-scope model

Rendered RFC

Links

@giortzisg
giortzisgforce-pushed the rfc/scope-model-for-go branch from 472b0ae to 2f73adfCompareMarch 19, 2026 11:24
@giortzisggiortzisg self-assigned this Mar 19, 2026
@giortzisg
giortzisg marked this pull request as ready for review March 19, 2026 11:25
@linear-code

Copy link
Copy Markdown

@sl0thentr0pysl0thentr0py left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

While I mostly understand the reasoning behind this RFC, and also partially agree with the arguments set forth, some considerations and comments:

Why 3 Scopes?

  • the whole point of the other 3 scope RFC was to make our scope more in line with otel copy-on-write context (which is the same design as go context) for POTEL (= bidirectional flow between sentry <-> otel)
  • if we already make our scope context like in this RFC suggests, we don't even need 3 scopes - just a global and a context-like scope suffices
  • the currentScope especially is really weird here because all it needs to hold is a span reference but we make it hold all the other stuff like tags and data and if we already have a copy-on-write structure we don't need the added complexity
  • honestly, since POTEL is now a dead project and we are already considering reverting it in JS, I'm not sure this whole 3-scope thing is even necessary. I'm definitely postpoining it and might not do it at all in Ruby, for instance.

Breaking Changes and Migration

We need a proper pathway for migration if we do this, so please add more clarification on this in the RFC.

Divergence

If we go forward with this in go, it will certainly create short term (if not permanent) divergence between go and other SDKs, something we have to be aware of and have buy-in from relevant people.


### Cons

- Major change from current SDK architecture, both for us and the users.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

we need concrete examples here on what migration would mean for the users and how much code they need to change

@giortzisg

Copy link
Copy Markdown
Author

The three scope model mapping section is mostly there for associating how the proposal would work when compared to the old approach.

I also agree that we don't really need the three scopes model (or at least limit it to only two scopes) for it to actually work, so let me rework the format a bit to be more clear.

@cleptric

Copy link
Copy Markdown
Member

As discussed offline, I'm in general happy with this approach, but we should include how a new span API interacts with the new scope model.

@giortzisg
giortzisg requested review from cleptric and sl0thentr0py and removed request for cleptricApril 7, 2026 10:25
Comment threadtext/0156-scope-model-for-go.md
Comment threadtext/0156-scope-model-for-go.md
Comment threadtext/0156-scope-model-for-go.md
#### Hub-in-context APIs

- SetHubOnContext(ctx, hub) and GetHubFromContext(ctx) stop being the primary user-facing propagation mechanism.
- Users should no longer manually clone hubs for request/task isolation, just pass the correct context.Context.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

this assumes that that go context forking semantics for concurrency/isolation are the same as what we were doing before. Does this hold for all cases where we manually forked before?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

That's a nice observation. I would say yes, since each scope.fork snapshot is essentially a different context. For forks that prevented mutability CoW guarantees that and for forks that are a snapshot of scope state, the mechanism now would be the ctx.

The only thing I can think of is CurrentHub.Clone() which becomes completely redundant under our model, since ctx and global scope would merge anyways on send.

Comment threadtext/0156-scope-model-for-go.md Outdated
#### Interaction with scope model

Under the proposed scope model, scope if only an infromation carrier and is no longer responsible for owning tracing state. The `context.Context` carries both the scope and active span state.
This means that `StartSpan` is also a scope-boundary operation and derived scopes already contain the previously inherited local state. Under this, the SDK does not need to merge separate scopes when a span ends. Semanticaly, the model gets simplified to:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

💯

Sign up for freeto 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.

5 participants

@giortzisg@cleptric@dingsdax@sl0thentr0py@lcian
, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' rfc(decision): scope model RFC for Go by giortzisg · Pull Request #156 · getsentry/rfcs · GitHub
Skip to content

rfc(decision): scope model RFC for Go - #156

Open
giortzisg wants to merge 7 commits into
mainfrom
rfc/scope-model-for-go
Open

rfc(decision): scope model RFC for Go#156
giortzisg wants to merge 7 commits into
mainfrom
rfc/scope-model-for-go

Conversation

@giortzisg

@giortzisggiortzisg commented Mar 19, 2026

Copy link
Copy Markdown

This RFC evaluates how sentry-go should model scope state so it can align with Sentry’s three-scope model

Rendered RFC

Links

@giortzisg
giortzisgforce-pushed the rfc/scope-model-for-go branch from 472b0ae to 2f73adfCompareMarch 19, 2026 11:24
@giortzisggiortzisg self-assigned this Mar 19, 2026
@giortzisg
giortzisg marked this pull request as ready for review March 19, 2026 11:25
@linear-code

Copy link
Copy Markdown

@sl0thentr0pysl0thentr0py left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

While I mostly understand the reasoning behind this RFC, and also partially agree with the arguments set forth, some considerations and comments:

Why 3 Scopes?

  • the whole point of the other 3 scope RFC was to make our scope more in line with otel copy-on-write context (which is the same design as go context) for POTEL (= bidirectional flow between sentry <-> otel)
  • if we already make our scope context like in this RFC suggests, we don't even need 3 scopes - just a global and a context-like scope suffices
  • the currentScope especially is really weird here because all it needs to hold is a span reference but we make it hold all the other stuff like tags and data and if we already have a copy-on-write structure we don't need the added complexity
  • honestly, since POTEL is now a dead project and we are already considering reverting it in JS, I'm not sure this whole 3-scope thing is even necessary. I'm definitely postpoining it and might not do it at all in Ruby, for instance.

Breaking Changes and Migration

We need a proper pathway for migration if we do this, so please add more clarification on this in the RFC.

Divergence

If we go forward with this in go, it will certainly create short term (if not permanent) divergence between go and other SDKs, something we have to be aware of and have buy-in from relevant people.


### Cons

- Major change from current SDK architecture, both for us and the users.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

we need concrete examples here on what migration would mean for the users and how much code they need to change

@giortzisg

Copy link
Copy Markdown
Author

The three scope model mapping section is mostly there for associating how the proposal would work when compared to the old approach.

I also agree that we don't really need the three scopes model (or at least limit it to only two scopes) for it to actually work, so let me rework the format a bit to be more clear.

@cleptric

Copy link
Copy Markdown
Member

As discussed offline, I'm in general happy with this approach, but we should include how a new span API interacts with the new scope model.

@giortzisg
giortzisg requested review from cleptric and sl0thentr0py and removed request for cleptricApril 7, 2026 10:25
Comment threadtext/0156-scope-model-for-go.md
Comment threadtext/0156-scope-model-for-go.md
Comment threadtext/0156-scope-model-for-go.md
#### Hub-in-context APIs

- SetHubOnContext(ctx, hub) and GetHubFromContext(ctx) stop being the primary user-facing propagation mechanism.
- Users should no longer manually clone hubs for request/task isolation, just pass the correct context.Context.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

this assumes that that go context forking semantics for concurrency/isolation are the same as what we were doing before. Does this hold for all cases where we manually forked before?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

That's a nice observation. I would say yes, since each scope.fork snapshot is essentially a different context. For forks that prevented mutability CoW guarantees that and for forks that are a snapshot of scope state, the mechanism now would be the ctx.

The only thing I can think of is CurrentHub.Clone() which becomes completely redundant under our model, since ctx and global scope would merge anyways on send.

Comment threadtext/0156-scope-model-for-go.md Outdated
#### Interaction with scope model

Under the proposed scope model, scope if only an infromation carrier and is no longer responsible for owning tracing state. The `context.Context` carries both the scope and active span state.
This means that `StartSpan` is also a scope-boundary operation and derived scopes already contain the previously inherited local state. Under this, the SDK does not need to merge separate scopes when a span ends. Semanticaly, the model gets simplified to:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

💯

Sign up for freeto 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.

5 participants

@giortzisg@cleptric@dingsdax@sl0thentr0py@lcian
, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' rfc(decision): scope model RFC for Go by giortzisg · Pull Request #156 · getsentry/rfcs · GitHub
Skip to content

rfc(decision): scope model RFC for Go - #156

Open
giortzisg wants to merge 7 commits into
mainfrom
rfc/scope-model-for-go
Open

rfc(decision): scope model RFC for Go#156
giortzisg wants to merge 7 commits into
mainfrom
rfc/scope-model-for-go

Conversation

@giortzisg

@giortzisggiortzisg commented Mar 19, 2026

Copy link
Copy Markdown

This RFC evaluates how sentry-go should model scope state so it can align with Sentry’s three-scope model

Rendered RFC

Links

@giortzisg
giortzisgforce-pushed the rfc/scope-model-for-go branch from 472b0ae to 2f73adfCompareMarch 19, 2026 11:24
@giortzisggiortzisg self-assigned this Mar 19, 2026
@giortzisg
giortzisg marked this pull request as ready for review March 19, 2026 11:25
@linear-code

Copy link
Copy Markdown

@sl0thentr0pysl0thentr0py left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

While I mostly understand the reasoning behind this RFC, and also partially agree with the arguments set forth, some considerations and comments:

Why 3 Scopes?

  • the whole point of the other 3 scope RFC was to make our scope more in line with otel copy-on-write context (which is the same design as go context) for POTEL (= bidirectional flow between sentry <-> otel)
  • if we already make our scope context like in this RFC suggests, we don't even need 3 scopes - just a global and a context-like scope suffices
  • the currentScope especially is really weird here because all it needs to hold is a span reference but we make it hold all the other stuff like tags and data and if we already have a copy-on-write structure we don't need the added complexity
  • honestly, since POTEL is now a dead project and we are already considering reverting it in JS, I'm not sure this whole 3-scope thing is even necessary. I'm definitely postpoining it and might not do it at all in Ruby, for instance.

Breaking Changes and Migration

We need a proper pathway for migration if we do this, so please add more clarification on this in the RFC.

Divergence

If we go forward with this in go, it will certainly create short term (if not permanent) divergence between go and other SDKs, something we have to be aware of and have buy-in from relevant people.


### Cons

- Major change from current SDK architecture, both for us and the users.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

we need concrete examples here on what migration would mean for the users and how much code they need to change

@giortzisg

Copy link
Copy Markdown
Author

The three scope model mapping section is mostly there for associating how the proposal would work when compared to the old approach.

I also agree that we don't really need the three scopes model (or at least limit it to only two scopes) for it to actually work, so let me rework the format a bit to be more clear.

@cleptric

Copy link
Copy Markdown
Member

As discussed offline, I'm in general happy with this approach, but we should include how a new span API interacts with the new scope model.

@giortzisg
giortzisg requested review from cleptric and sl0thentr0py and removed request for cleptricApril 7, 2026 10:25
Comment threadtext/0156-scope-model-for-go.md
Comment threadtext/0156-scope-model-for-go.md
Comment threadtext/0156-scope-model-for-go.md
#### Hub-in-context APIs

- SetHubOnContext(ctx, hub) and GetHubFromContext(ctx) stop being the primary user-facing propagation mechanism.
- Users should no longer manually clone hubs for request/task isolation, just pass the correct context.Context.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

this assumes that that go context forking semantics for concurrency/isolation are the same as what we were doing before. Does this hold for all cases where we manually forked before?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

That's a nice observation. I would say yes, since each scope.fork snapshot is essentially a different context. For forks that prevented mutability CoW guarantees that and for forks that are a snapshot of scope state, the mechanism now would be the ctx.

The only thing I can think of is CurrentHub.Clone() which becomes completely redundant under our model, since ctx and global scope would merge anyways on send.

Comment threadtext/0156-scope-model-for-go.md Outdated
#### Interaction with scope model

Under the proposed scope model, scope if only an infromation carrier and is no longer responsible for owning tracing state. The `context.Context` carries both the scope and active span state.
This means that `StartSpan` is also a scope-boundary operation and derived scopes already contain the previously inherited local state. Under this, the SDK does not need to merge separate scopes when a span ends. Semanticaly, the model gets simplified to:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

💯

Sign up for freeto 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.

5 participants

@giortzisg@cleptric@dingsdax@sl0thentr0py@lcian
, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })(); rfc(decision): scope model RFC for Go by giortzisg · Pull Request #156 · getsentry/rfcs · GitHub
Skip to content

rfc(decision): scope model RFC for Go - #156

Open
giortzisg wants to merge 7 commits into
mainfrom
rfc/scope-model-for-go
Open

rfc(decision): scope model RFC for Go#156
giortzisg wants to merge 7 commits into
mainfrom
rfc/scope-model-for-go

Conversation

@giortzisg

@giortzisggiortzisg commented Mar 19, 2026

Copy link
Copy Markdown

This RFC evaluates how sentry-go should model scope state so it can align with Sentry’s three-scope model

Rendered RFC

Links

@giortzisg
giortzisgforce-pushed the rfc/scope-model-for-go branch from 472b0ae to 2f73adfCompareMarch 19, 2026 11:24
@giortzisggiortzisg self-assigned this Mar 19, 2026
@giortzisg
giortzisg marked this pull request as ready for review March 19, 2026 11:25
@linear-code

Copy link
Copy Markdown

@sl0thentr0pysl0thentr0py left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

While I mostly understand the reasoning behind this RFC, and also partially agree with the arguments set forth, some considerations and comments:

Why 3 Scopes?

  • the whole point of the other 3 scope RFC was to make our scope more in line with otel copy-on-write context (which is the same design as go context) for POTEL (= bidirectional flow between sentry <-> otel)
  • if we already make our scope context like in this RFC suggests, we don't even need 3 scopes - just a global and a context-like scope suffices
  • the currentScope especially is really weird here because all it needs to hold is a span reference but we make it hold all the other stuff like tags and data and if we already have a copy-on-write structure we don't need the added complexity
  • honestly, since POTEL is now a dead project and we are already considering reverting it in JS, I'm not sure this whole 3-scope thing is even necessary. I'm definitely postpoining it and might not do it at all in Ruby, for instance.

Breaking Changes and Migration

We need a proper pathway for migration if we do this, so please add more clarification on this in the RFC.

Divergence

If we go forward with this in go, it will certainly create short term (if not permanent) divergence between go and other SDKs, something we have to be aware of and have buy-in from relevant people.


### Cons

- Major change from current SDK architecture, both for us and the users.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

we need concrete examples here on what migration would mean for the users and how much code they need to change

@giortzisg

Copy link
Copy Markdown
Author

The three scope model mapping section is mostly there for associating how the proposal would work when compared to the old approach.

I also agree that we don't really need the three scopes model (or at least limit it to only two scopes) for it to actually work, so let me rework the format a bit to be more clear.

@cleptric

Copy link
Copy Markdown
Member

As discussed offline, I'm in general happy with this approach, but we should include how a new span API interacts with the new scope model.

@giortzisg
giortzisg requested review from cleptric and sl0thentr0py and removed request for cleptricApril 7, 2026 10:25
Comment threadtext/0156-scope-model-for-go.md
Comment threadtext/0156-scope-model-for-go.md
Comment threadtext/0156-scope-model-for-go.md
#### Hub-in-context APIs

- SetHubOnContext(ctx, hub) and GetHubFromContext(ctx) stop being the primary user-facing propagation mechanism.
- Users should no longer manually clone hubs for request/task isolation, just pass the correct context.Context.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

this assumes that that go context forking semantics for concurrency/isolation are the same as what we were doing before. Does this hold for all cases where we manually forked before?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

That's a nice observation. I would say yes, since each scope.fork snapshot is essentially a different context. For forks that prevented mutability CoW guarantees that and for forks that are a snapshot of scope state, the mechanism now would be the ctx.

The only thing I can think of is CurrentHub.Clone() which becomes completely redundant under our model, since ctx and global scope would merge anyways on send.

Comment threadtext/0156-scope-model-for-go.md Outdated
#### Interaction with scope model

Under the proposed scope model, scope if only an infromation carrier and is no longer responsible for owning tracing state. The `context.Context` carries both the scope and active span state.
This means that `StartSpan` is also a scope-boundary operation and derived scopes already contain the previously inherited local state. Under this, the SDK does not need to merge separate scopes when a span ends. Semanticaly, the model gets simplified to:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

💯

Sign up for freeto 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.

5 participants

@giortzisg@cleptric@dingsdax@sl0thentr0py@lcian