Skip to content

Re-run acuantia through the rebuilt migrate tooling, against the hand port as ground truth #59

Description

@ihistand

The acuantia port was done by hand: eight Python codemods, ~740 rewritten sites, 53 files descoped, and roughly a dozen run-and-classify cycles. Everything learned from it has since been built into the tooling (#53, #54, #55, #56, #57, #58, plus migrate-fix and GROUP BY ALL).

The point of this run is not to migrate acuantia again — it is to measure how much of that work the tooling now does on its own. It is a rare opportunity: the hand-ported repo still exists, so there is a ground truth to diff against, which no synthetic fixture provides.

Method

Convert the ORIGINAL source, then walk the three phases:

sqlanvil migrate-dataform <acuantia-gcp-dataform> /tmp/acuantia-auto
cd /tmp/acuantia-auto && ./scripts/introspect_all.sh
sqlanvil migrate-fix .

Then diff /tmp/acuantia-auto against acuantia-sqlanvil (the hand port) and read the report.

What to measure

Coverage per class. For each construct the hand port handled, did the tool do it, and identically? The classes and their hand-port counts, as the yardstick:

classsitesexpected owner
SELECT * EXCEPT141migrate-fix
identifier casing~700 refsnow moot — folded at extract
COLLATE(x, '')66converter
NOT ENFORCED149converter (commented)
GROUP BY ALL61migrate-fix
type names / timezones / literals252converter
SAFE_CAST37converter
backticks93converter
SPLIT / DAYOFWEEK / DATETIME type21converter
ARRAY<STRUCT>6report only, by design

Where the tool and the hand port disagree. The interesting output. Three kinds, and they mean different things: the tool did something the hand port did not (possibly better, possibly wrong), the hand port did something the tool missed (a gap to file), or both acted and differ (read carefully — this is where a silent semantic difference would hide).

Whether the report is actually usable as a handover. Does the class-first to-do list, the mechanical/needs-decision split and the per-site SQL let someone pick the project up? That was #56's whole claim and it has never been tested on something this size.

How much residue is genuinely a decision. The hand port needed four descope calls (dialpad, gemstone AI/BQML, the metadata views, jaro-winkler + the manufacturer chain). Those are business questions and should still appear as needs-decision — if the tool has quietly ported them instead, that is a bug in the report, not a win.

Decisions this should settle

  • Whether to automate the ARRAY<STRUCT> collapse.migrate-dataform: convert ARRAY&lt;STRUCT&gt; rather than only flagging it #54 left it as a recommendation because it restructures the model. acuantia has the real shape — six sites, one file, feeding one flattening operation — so it is the right place to judge whether the graph evidence is strong enough to act on.
  • Whether migrate-fix should also carry the remaining flag-class conversions (QUALIFY, PARSE_DATE, FARM_FINGERPRINT, json_extract_array), or whether they stay reported.
  • What the residue actually looks like on a project of this size, which is the number that says whether "migrate without an agent" is realistic for anything beyond a small project.

Not in scope

Getting acuantia green. That was settled in #81: the migration is an exercise, not a deliverable. If the tooling produces a project that needs less hand-work than the original port did, this has answered its question.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

    , '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" + '
    Re-run acuantia through the rebuilt migrate tooling, against the hand port as ground truth · Issue #59 · SQLAnvil/sqlanvil · GitHub
    Skip to content

    Re-run acuantia through the rebuilt migrate tooling, against the hand port as ground truth #59

    Description

    @ihistand

    The acuantia port was done by hand: eight Python codemods, ~740 rewritten sites, 53 files descoped, and roughly a dozen run-and-classify cycles. Everything learned from it has since been built into the tooling (#53, #54, #55, #56, #57, #58, plus migrate-fix and GROUP BY ALL).

    The point of this run is not to migrate acuantia again — it is to measure how much of that work the tooling now does on its own. It is a rare opportunity: the hand-ported repo still exists, so there is a ground truth to diff against, which no synthetic fixture provides.

    Method

    Convert the ORIGINAL source, then walk the three phases:

    sqlanvil migrate-dataform <acuantia-gcp-dataform> /tmp/acuantia-auto
    cd /tmp/acuantia-auto && ./scripts/introspect_all.sh
    sqlanvil migrate-fix .
    

    Then diff /tmp/acuantia-auto against acuantia-sqlanvil (the hand port) and read the report.

    What to measure

    Coverage per class. For each construct the hand port handled, did the tool do it, and identically? The classes and their hand-port counts, as the yardstick:

    classsitesexpected owner
    SELECT * EXCEPT141migrate-fix
    identifier casing~700 refsnow moot — folded at extract
    COLLATE(x, '')66converter
    NOT ENFORCED149converter (commented)
    GROUP BY ALL61migrate-fix
    type names / timezones / literals252converter
    SAFE_CAST37converter
    backticks93converter
    SPLIT / DAYOFWEEK / DATETIME type21converter
    ARRAY<STRUCT>6report only, by design

    Where the tool and the hand port disagree. The interesting output. Three kinds, and they mean different things: the tool did something the hand port did not (possibly better, possibly wrong), the hand port did something the tool missed (a gap to file), or both acted and differ (read carefully — this is where a silent semantic difference would hide).

    Whether the report is actually usable as a handover. Does the class-first to-do list, the mechanical/needs-decision split and the per-site SQL let someone pick the project up? That was #56's whole claim and it has never been tested on something this size.

    How much residue is genuinely a decision. The hand port needed four descope calls (dialpad, gemstone AI/BQML, the metadata views, jaro-winkler + the manufacturer chain). Those are business questions and should still appear as needs-decision — if the tool has quietly ported them instead, that is a bug in the report, not a win.

    Decisions this should settle

    • Whether to automate the ARRAY<STRUCT> collapse.migrate-dataform: convert ARRAY&lt;STRUCT&gt; rather than only flagging it #54 left it as a recommendation because it restructures the model. acuantia has the real shape — six sites, one file, feeding one flattening operation — so it is the right place to judge whether the graph evidence is strong enough to act on.
    • Whether migrate-fix should also carry the remaining flag-class conversions (QUALIFY, PARSE_DATE, FARM_FINGERPRINT, json_extract_array), or whether they stay reported.
    • What the residue actually looks like on a project of this size, which is the number that says whether "migrate without an agent" is realistic for anything beyond a small project.

    Not in scope

    Getting acuantia green. That was settled in #81: the migration is an exercise, not a deliverable. If the tooling produces a project that needs less hand-work than the original port did, this has answered its question.

    Metadata

    Metadata

    Assignees

    No one assigned

      Labels

      No labels
      No labels

      Type

      No type

      Projects

      No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      , '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('^' + ".*" + ' Re-run acuantia through the rebuilt migrate tooling, against the hand port as ground truth · Issue #59 · SQLAnvil/sqlanvil · GitHub
      Skip to content

      Re-run acuantia through the rebuilt migrate tooling, against the hand port as ground truth #59

      Description

      @ihistand

      The acuantia port was done by hand: eight Python codemods, ~740 rewritten sites, 53 files descoped, and roughly a dozen run-and-classify cycles. Everything learned from it has since been built into the tooling (#53, #54, #55, #56, #57, #58, plus migrate-fix and GROUP BY ALL).

      The point of this run is not to migrate acuantia again — it is to measure how much of that work the tooling now does on its own. It is a rare opportunity: the hand-ported repo still exists, so there is a ground truth to diff against, which no synthetic fixture provides.

      Method

      Convert the ORIGINAL source, then walk the three phases:

      sqlanvil migrate-dataform <acuantia-gcp-dataform> /tmp/acuantia-auto
      cd /tmp/acuantia-auto && ./scripts/introspect_all.sh
      sqlanvil migrate-fix .
      

      Then diff /tmp/acuantia-auto against acuantia-sqlanvil (the hand port) and read the report.

      What to measure

      Coverage per class. For each construct the hand port handled, did the tool do it, and identically? The classes and their hand-port counts, as the yardstick:

      classsitesexpected owner
      SELECT * EXCEPT141migrate-fix
      identifier casing~700 refsnow moot — folded at extract
      COLLATE(x, '')66converter
      NOT ENFORCED149converter (commented)
      GROUP BY ALL61migrate-fix
      type names / timezones / literals252converter
      SAFE_CAST37converter
      backticks93converter
      SPLIT / DAYOFWEEK / DATETIME type21converter
      ARRAY<STRUCT>6report only, by design

      Where the tool and the hand port disagree. The interesting output. Three kinds, and they mean different things: the tool did something the hand port did not (possibly better, possibly wrong), the hand port did something the tool missed (a gap to file), or both acted and differ (read carefully — this is where a silent semantic difference would hide).

      Whether the report is actually usable as a handover. Does the class-first to-do list, the mechanical/needs-decision split and the per-site SQL let someone pick the project up? That was #56's whole claim and it has never been tested on something this size.

      How much residue is genuinely a decision. The hand port needed four descope calls (dialpad, gemstone AI/BQML, the metadata views, jaro-winkler + the manufacturer chain). Those are business questions and should still appear as needs-decision — if the tool has quietly ported them instead, that is a bug in the report, not a win.

      Decisions this should settle

      • Whether to automate the ARRAY<STRUCT> collapse.migrate-dataform: convert ARRAY&lt;STRUCT&gt; rather than only flagging it #54 left it as a recommendation because it restructures the model. acuantia has the real shape — six sites, one file, feeding one flattening operation — so it is the right place to judge whether the graph evidence is strong enough to act on.
      • Whether migrate-fix should also carry the remaining flag-class conversions (QUALIFY, PARSE_DATE, FARM_FINGERPRINT, json_extract_array), or whether they stay reported.
      • What the residue actually looks like on a project of this size, which is the number that says whether "migrate without an agent" is realistic for anything beyond a small project.

      Not in scope

      Getting acuantia green. That was settled in #81: the migration is an exercise, not a deliverable. If the tooling produces a project that needs less hand-work than the original port did, this has answered its question.

      Metadata

      Metadata

      Assignees

      No one assigned

        Labels

        No labels
        No labels

        Type

        No type

        Projects

        No projects

        Milestone

        No milestone

        Relationships

        None yet

        Development

        No branches or pull requests

        Issue actions

        , '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('^' + ".*" + ' Re-run acuantia through the rebuilt migrate tooling, against the hand port as ground truth · Issue #59 · SQLAnvil/sqlanvil · GitHub
        Skip to content

        Re-run acuantia through the rebuilt migrate tooling, against the hand port as ground truth #59

        Description

        @ihistand

        The acuantia port was done by hand: eight Python codemods, ~740 rewritten sites, 53 files descoped, and roughly a dozen run-and-classify cycles. Everything learned from it has since been built into the tooling (#53, #54, #55, #56, #57, #58, plus migrate-fix and GROUP BY ALL).

        The point of this run is not to migrate acuantia again — it is to measure how much of that work the tooling now does on its own. It is a rare opportunity: the hand-ported repo still exists, so there is a ground truth to diff against, which no synthetic fixture provides.

        Method

        Convert the ORIGINAL source, then walk the three phases:

        sqlanvil migrate-dataform <acuantia-gcp-dataform> /tmp/acuantia-auto
        cd /tmp/acuantia-auto && ./scripts/introspect_all.sh
        sqlanvil migrate-fix .
        

        Then diff /tmp/acuantia-auto against acuantia-sqlanvil (the hand port) and read the report.

        What to measure

        Coverage per class. For each construct the hand port handled, did the tool do it, and identically? The classes and their hand-port counts, as the yardstick:

        classsitesexpected owner
        SELECT * EXCEPT141migrate-fix
        identifier casing~700 refsnow moot — folded at extract
        COLLATE(x, '')66converter
        NOT ENFORCED149converter (commented)
        GROUP BY ALL61migrate-fix
        type names / timezones / literals252converter
        SAFE_CAST37converter
        backticks93converter
        SPLIT / DAYOFWEEK / DATETIME type21converter
        ARRAY<STRUCT>6report only, by design

        Where the tool and the hand port disagree. The interesting output. Three kinds, and they mean different things: the tool did something the hand port did not (possibly better, possibly wrong), the hand port did something the tool missed (a gap to file), or both acted and differ (read carefully — this is where a silent semantic difference would hide).

        Whether the report is actually usable as a handover. Does the class-first to-do list, the mechanical/needs-decision split and the per-site SQL let someone pick the project up? That was #56's whole claim and it has never been tested on something this size.

        How much residue is genuinely a decision. The hand port needed four descope calls (dialpad, gemstone AI/BQML, the metadata views, jaro-winkler + the manufacturer chain). Those are business questions and should still appear as needs-decision — if the tool has quietly ported them instead, that is a bug in the report, not a win.

        Decisions this should settle

        • Whether to automate the ARRAY<STRUCT> collapse.migrate-dataform: convert ARRAY&lt;STRUCT&gt; rather than only flagging it #54 left it as a recommendation because it restructures the model. acuantia has the real shape — six sites, one file, feeding one flattening operation — so it is the right place to judge whether the graph evidence is strong enough to act on.
        • Whether migrate-fix should also carry the remaining flag-class conversions (QUALIFY, PARSE_DATE, FARM_FINGERPRINT, json_extract_array), or whether they stay reported.
        • What the residue actually looks like on a project of this size, which is the number that says whether "migrate without an agent" is realistic for anything beyond a small project.

        Not in scope

        Getting acuantia green. That was settled in #81: the migration is an exercise, not a deliverable. If the tooling produces a project that needs less hand-work than the original port did, this has answered its question.

        Metadata

        Metadata

        Assignees

        No one assigned

          Labels

          No labels
          No labels

          Type

          No type

          Projects

          No projects

          Milestone

          No milestone

          Relationships

          None yet

          Development

          No branches or pull requests

          Issue actions

          , '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" + ' Re-run acuantia through the rebuilt migrate tooling, against the hand port as ground truth · Issue #59 · SQLAnvil/sqlanvil · GitHub
          Skip to content

          Re-run acuantia through the rebuilt migrate tooling, against the hand port as ground truth #59

          Description

          @ihistand

          The acuantia port was done by hand: eight Python codemods, ~740 rewritten sites, 53 files descoped, and roughly a dozen run-and-classify cycles. Everything learned from it has since been built into the tooling (#53, #54, #55, #56, #57, #58, plus migrate-fix and GROUP BY ALL).

          The point of this run is not to migrate acuantia again — it is to measure how much of that work the tooling now does on its own. It is a rare opportunity: the hand-ported repo still exists, so there is a ground truth to diff against, which no synthetic fixture provides.

          Method

          Convert the ORIGINAL source, then walk the three phases:

          sqlanvil migrate-dataform <acuantia-gcp-dataform> /tmp/acuantia-auto
          cd /tmp/acuantia-auto && ./scripts/introspect_all.sh
          sqlanvil migrate-fix .
          

          Then diff /tmp/acuantia-auto against acuantia-sqlanvil (the hand port) and read the report.

          What to measure

          Coverage per class. For each construct the hand port handled, did the tool do it, and identically? The classes and their hand-port counts, as the yardstick:

          classsitesexpected owner
          SELECT * EXCEPT141migrate-fix
          identifier casing~700 refsnow moot — folded at extract
          COLLATE(x, '')66converter
          NOT ENFORCED149converter (commented)
          GROUP BY ALL61migrate-fix
          type names / timezones / literals252converter
          SAFE_CAST37converter
          backticks93converter
          SPLIT / DAYOFWEEK / DATETIME type21converter
          ARRAY<STRUCT>6report only, by design

          Where the tool and the hand port disagree. The interesting output. Three kinds, and they mean different things: the tool did something the hand port did not (possibly better, possibly wrong), the hand port did something the tool missed (a gap to file), or both acted and differ (read carefully — this is where a silent semantic difference would hide).

          Whether the report is actually usable as a handover. Does the class-first to-do list, the mechanical/needs-decision split and the per-site SQL let someone pick the project up? That was #56's whole claim and it has never been tested on something this size.

          How much residue is genuinely a decision. The hand port needed four descope calls (dialpad, gemstone AI/BQML, the metadata views, jaro-winkler + the manufacturer chain). Those are business questions and should still appear as needs-decision — if the tool has quietly ported them instead, that is a bug in the report, not a win.

          Decisions this should settle

          • Whether to automate the ARRAY<STRUCT> collapse.migrate-dataform: convert ARRAY&lt;STRUCT&gt; rather than only flagging it #54 left it as a recommendation because it restructures the model. acuantia has the real shape — six sites, one file, feeding one flattening operation — so it is the right place to judge whether the graph evidence is strong enough to act on.
          • Whether migrate-fix should also carry the remaining flag-class conversions (QUALIFY, PARSE_DATE, FARM_FINGERPRINT, json_extract_array), or whether they stay reported.
          • What the residue actually looks like on a project of this size, which is the number that says whether "migrate without an agent" is realistic for anything beyond a small project.

          Not in scope

          Getting acuantia green. That was settled in #81: the migration is an exercise, not a deliverable. If the tooling produces a project that needs less hand-work than the original port did, this has answered its question.

          Metadata

          Metadata

          Assignees

          No one assigned

            Labels

            No labels
            No labels

            Type

            No type

            Projects

            No projects

            Milestone

            No milestone

            Relationships

            None yet

            Development

            No branches or pull requests

            Issue actions

            , '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('^' + ".*" + ' Re-run acuantia through the rebuilt migrate tooling, against the hand port as ground truth · Issue #59 · SQLAnvil/sqlanvil · GitHub
            Skip to content

            Re-run acuantia through the rebuilt migrate tooling, against the hand port as ground truth #59

            Description

            @ihistand

            The acuantia port was done by hand: eight Python codemods, ~740 rewritten sites, 53 files descoped, and roughly a dozen run-and-classify cycles. Everything learned from it has since been built into the tooling (#53, #54, #55, #56, #57, #58, plus migrate-fix and GROUP BY ALL).

            The point of this run is not to migrate acuantia again — it is to measure how much of that work the tooling now does on its own. It is a rare opportunity: the hand-ported repo still exists, so there is a ground truth to diff against, which no synthetic fixture provides.

            Method

            Convert the ORIGINAL source, then walk the three phases:

            sqlanvil migrate-dataform <acuantia-gcp-dataform> /tmp/acuantia-auto
            cd /tmp/acuantia-auto && ./scripts/introspect_all.sh
            sqlanvil migrate-fix .
            

            Then diff /tmp/acuantia-auto against acuantia-sqlanvil (the hand port) and read the report.

            What to measure

            Coverage per class. For each construct the hand port handled, did the tool do it, and identically? The classes and their hand-port counts, as the yardstick:

            classsitesexpected owner
            SELECT * EXCEPT141migrate-fix
            identifier casing~700 refsnow moot — folded at extract
            COLLATE(x, '')66converter
            NOT ENFORCED149converter (commented)
            GROUP BY ALL61migrate-fix
            type names / timezones / literals252converter
            SAFE_CAST37converter
            backticks93converter
            SPLIT / DAYOFWEEK / DATETIME type21converter
            ARRAY<STRUCT>6report only, by design

            Where the tool and the hand port disagree. The interesting output. Three kinds, and they mean different things: the tool did something the hand port did not (possibly better, possibly wrong), the hand port did something the tool missed (a gap to file), or both acted and differ (read carefully — this is where a silent semantic difference would hide).

            Whether the report is actually usable as a handover. Does the class-first to-do list, the mechanical/needs-decision split and the per-site SQL let someone pick the project up? That was #56's whole claim and it has never been tested on something this size.

            How much residue is genuinely a decision. The hand port needed four descope calls (dialpad, gemstone AI/BQML, the metadata views, jaro-winkler + the manufacturer chain). Those are business questions and should still appear as needs-decision — if the tool has quietly ported them instead, that is a bug in the report, not a win.

            Decisions this should settle

            • Whether to automate the ARRAY<STRUCT> collapse.migrate-dataform: convert ARRAY&lt;STRUCT&gt; rather than only flagging it #54 left it as a recommendation because it restructures the model. acuantia has the real shape — six sites, one file, feeding one flattening operation — so it is the right place to judge whether the graph evidence is strong enough to act on.
            • Whether migrate-fix should also carry the remaining flag-class conversions (QUALIFY, PARSE_DATE, FARM_FINGERPRINT, json_extract_array), or whether they stay reported.
            • What the residue actually looks like on a project of this size, which is the number that says whether "migrate without an agent" is realistic for anything beyond a small project.

            Not in scope

            Getting acuantia green. That was settled in #81: the migration is an exercise, not a deliverable. If the tooling produces a project that needs less hand-work than the original port did, this has answered its question.

            Metadata

            Metadata

            Assignees

            No one assigned

              Labels

              No labels
              No labels

              Type

              No type

              Projects

              No projects

              Milestone

              No milestone

              Relationships

              None yet

              Development

              No branches or pull requests

              Issue actions

              , '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); } })(); })(); Re-run acuantia through the rebuilt migrate tooling, against the hand port as ground truth · Issue #59 · SQLAnvil/sqlanvil · GitHub
              Skip to content

              Re-run acuantia through the rebuilt migrate tooling, against the hand port as ground truth #59

              Description

              @ihistand

              The acuantia port was done by hand: eight Python codemods, ~740 rewritten sites, 53 files descoped, and roughly a dozen run-and-classify cycles. Everything learned from it has since been built into the tooling (#53, #54, #55, #56, #57, #58, plus migrate-fix and GROUP BY ALL).

              The point of this run is not to migrate acuantia again — it is to measure how much of that work the tooling now does on its own. It is a rare opportunity: the hand-ported repo still exists, so there is a ground truth to diff against, which no synthetic fixture provides.

              Method

              Convert the ORIGINAL source, then walk the three phases:

              sqlanvil migrate-dataform <acuantia-gcp-dataform> /tmp/acuantia-auto
              cd /tmp/acuantia-auto && ./scripts/introspect_all.sh
              sqlanvil migrate-fix .
              

              Then diff /tmp/acuantia-auto against acuantia-sqlanvil (the hand port) and read the report.

              What to measure

              Coverage per class. For each construct the hand port handled, did the tool do it, and identically? The classes and their hand-port counts, as the yardstick:

              classsitesexpected owner
              SELECT * EXCEPT141migrate-fix
              identifier casing~700 refsnow moot — folded at extract
              COLLATE(x, '')66converter
              NOT ENFORCED149converter (commented)
              GROUP BY ALL61migrate-fix
              type names / timezones / literals252converter
              SAFE_CAST37converter
              backticks93converter
              SPLIT / DAYOFWEEK / DATETIME type21converter
              ARRAY<STRUCT>6report only, by design

              Where the tool and the hand port disagree. The interesting output. Three kinds, and they mean different things: the tool did something the hand port did not (possibly better, possibly wrong), the hand port did something the tool missed (a gap to file), or both acted and differ (read carefully — this is where a silent semantic difference would hide).

              Whether the report is actually usable as a handover. Does the class-first to-do list, the mechanical/needs-decision split and the per-site SQL let someone pick the project up? That was #56's whole claim and it has never been tested on something this size.

              How much residue is genuinely a decision. The hand port needed four descope calls (dialpad, gemstone AI/BQML, the metadata views, jaro-winkler + the manufacturer chain). Those are business questions and should still appear as needs-decision — if the tool has quietly ported them instead, that is a bug in the report, not a win.

              Decisions this should settle

              • Whether to automate the ARRAY<STRUCT> collapse.migrate-dataform: convert ARRAY&lt;STRUCT&gt; rather than only flagging it #54 left it as a recommendation because it restructures the model. acuantia has the real shape — six sites, one file, feeding one flattening operation — so it is the right place to judge whether the graph evidence is strong enough to act on.
              • Whether migrate-fix should also carry the remaining flag-class conversions (QUALIFY, PARSE_DATE, FARM_FINGERPRINT, json_extract_array), or whether they stay reported.
              • What the residue actually looks like on a project of this size, which is the number that says whether "migrate without an agent" is realistic for anything beyond a small project.

              Not in scope

              Getting acuantia green. That was settled in #81: the migration is an exercise, not a deliverable. If the tooling produces a project that needs less hand-work than the original port did, this has answered its question.

              Metadata

              Metadata

              Assignees

              No one assigned

                Labels

                No labels
                No labels

                Type

                No type

                Projects

                No projects

                Milestone

                No milestone

                Relationships

                None yet

                Development

                No branches or pull requests

                Issue actions