') + ')', '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('^' + ".*" + ', '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" + ', '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('^' + ".*" + ', '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); } })(); })(); fix(registry): `latest` now means default branch HEAD, not newest tag by jrob5756 · Pull Request #157 · microsoft/conductor · GitHub
Skip to content

fix(registry): latest now means default branch HEAD, not newest tag - #157

Merged
Jason Robert (jrob5756) merged 1 commit into
mainfrom
fix/registry-default-branch
May 6, 2026
Merged

fix(registry): latest now means default branch HEAD, not newest tag#157
Jason Robert (jrob5756) merged 1 commit into
mainfrom
fix/registry-default-branch

Conversation

@jrob5756

Copy link
Copy Markdown
Collaborator

Summary

Changes the default ref resolution for workflow registries: a bare `name@registry` reference now always resolves to the default branch HEAD, instead of the newest git tag.

Why

The previous behavior was surprising. As soon as a registry repo had a single tag, bare references silently froze at that tag and stopped picking up commits to `main`. A user pushing to their registry's main branch and running `conductor registry update` would see no change — because `latest` had quietly switched from "newest commit" to "newest tag" the moment the first tag was created.

The new model matches what most users expect from a development-time tool:

ReferenceResolves to
`qa-bot`default registry, default branch HEAD
`qa-bot#latest`same as above
`qa-bot#v1.2.3`explicit tag
`qa-bot#main`explicit branch
`qa-bot#abc123`explicit commit SHA

Tags are still first-class refs — pin explicitly when you want a release.

Impact

  • One fewer GitHub API call on the hot path of bare-name fetches (no more `list_tags`).
  • Tag listing is still used for the "Latest tags:" display in `registry list`/`show`.
  • Branch HEAD is still re-resolved to a fresh commit SHA on every fetch, so cache invalidation is automatic.

Tests

  • Updated tests in `test_version_resolver.py` to match the new semantics.
  • Full suite: 2379 passed, 9 skipped.
  • Ruff lint + format clean.

Previously, when no `#<ref>` was given, conductor resolved `latest` to
the newest semver-sorted git tag if any tags existed, falling back to
the default branch only when no tags existed. This was surprising:
once a registry had a single tag, bare `name@registry` references
silently froze at that tag and stopped picking up commits to main.
New semantics:
* No ref / `#latest` -> default branch HEAD (always)
* Explicit `#<ref>` -> use that ref verbatim (tag, branch, or SHA)
Pin to a tagged release explicitly with `name@registry#v1.2.3`.
Tag listing is still used for the 'Latest tags:' display in
`registry list`/`show`, just not for default ref resolution. This
also removes one GitHub API call from the hot path of bare-name
fetches.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@jrob5756
Jason Robert (jrob5756) merged commit f39b70a into mainMay 6, 2026
2 checks passed
@jrob5756
Jason Robert (jrob5756) deleted the fix/registry-default-branch branch May 6, 2026 02:27
Jason Robert (jrob5756) added a commit that referenced this pull request May 6, 2026
- conductor resume flag parity with run (#158)
- reasoning effort displayed in dashboard (#160)
- iteration_limit_reached/resolved events for dashboard (#162)
- registry latest now means default branch HEAD, not newest tag (#157)
- forbid extra fields on Agent/Parallel/ForEach/Workflow schemas (#159)
- pretty-print tool args/results in dashboard events (#161)
- capture uv stdout+stderr on Windows install failure (#156)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
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.

1 participant

@jrob5756