Skip to content

[finding] No live-Postgres coverage of the record-data OCC seam — the driver shape that broke it is only ever a hand-made fixture #13567

Description

@zhuangjianguo

Recording a coverage gap found while fixing #13382. Not a defect in current behaviour#13382's own repair is landed with pins that fail loudly. This is about which backends those pins ever run against, which is a CI-topology decision rather than a bug fix, so it is filed instead of expanded into that PR.

What #13382 was

The record-data optimistic-concurrency gate (assertVersionOf / assertVersionMatch in packages/metadata-protocol/src/protocol.ts) compared the record's updated_at against the caller's token with String(v) on both sides. On Postgres — the production default driver — updated_at arrives as a JS Date, so the comparison ran against Sun Aug 30 2026 18:19:25 GMT+0800 (China Standard Time) while the client echoed back the 2026-08-30T10:19:25.947Z its own GET had served. Every guarded save conflicted, on records nobody had touched.

Why it survived, stated as a coverage fact

Every existing OCC pin drives ISO text on both sides of the comparison — a memory or mocked engine, or SQLite, all of which round-trip canonical ISO strings. Those pins were green the entire time the production default driver refused every write. The discriminating input is the driver's Date, and nothing in the repo ever produced it into this seam.

The gap that is still open after the fix

Temporal Conformance (live PG + MySQL) — the required job where a real Postgres exists — runs pnpm --filter @objectstack/driver-sql test. The OCC seam lives in @objectstack/metadata-protocol, which has no driver dependency and must not grow one (the layering runs the other way). So:

  • the seam's new regression suite pins the behaviour given each input shape, using a hand-made Date — which is correct and sufficient to catch a revert of the repair;
  • but the composed fact that made it a production bug — this driver, against this seam, hands over a Date — is asserted by nothing. It was measured by hand against a real PostgreSQL 16 while fixing the card, and that measurement is not something the repo carries.

The class is the one AGENTS.md already names elsewhere: a green suite that is not a suite, on the path a double was introduced for.

Options, for whoever triages this

  1. A driver-side characterisation pin in driver-sql. Assert, under the live matrix, that a row's updated_at read back on Postgres/MySQL is a Date whose String() loses milliseconds and carries the process zone. Cheapest by a wide margin, lands in a package already inside the job, and pins the exact fact the seam's assumption was wrong about. It pins a decision the driver states deliberately (withPostgresCalendarDayAsText: "timestamptz / timestamp are deliberately untouched: those are instants, a Date is the right materialisation for them"), so it is not over-pinning.
  2. An end-to-end OCC cell in the live job, from a package that legitimately depends on both sides (packages/rest and packages/runtime both do). Highest fidelity, but it widens a required job's package set, which is why this is a decision and not a patch.
  3. Accept the gap and rely on the seam-level pins. Defensible; worth recording as a decision rather than leaving it as an accident.

Recommendation: option 1, and only option 1 unless someone wants the wider cell for its own reasons.

Wider question this raises, deliberately not answered here

updated_at is not the only value whose runtime type differs between the Date-returning drivers (Postgres, MySQL, MongoDB) and the ISO-text ones (the SQLite family, memory). Whether other consumers compare or format it while only ever being tested on the text side is a sweep, not a fix, and would be its own card.

Metadata

Metadata

Assignees

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" + '
    [finding] No live-Postgres coverage of the record-data OCC seam — the driver shape that broke it is only ever a hand-made fixture · Issue #13567 · objectstack-ai/objectstack · GitHub
    Skip to content

    [finding] No live-Postgres coverage of the record-data OCC seam — the driver shape that broke it is only ever a hand-made fixture #13567

    Description

    @zhuangjianguo

    Recording a coverage gap found while fixing #13382. Not a defect in current behaviour#13382's own repair is landed with pins that fail loudly. This is about which backends those pins ever run against, which is a CI-topology decision rather than a bug fix, so it is filed instead of expanded into that PR.

    What #13382 was

    The record-data optimistic-concurrency gate (assertVersionOf / assertVersionMatch in packages/metadata-protocol/src/protocol.ts) compared the record's updated_at against the caller's token with String(v) on both sides. On Postgres — the production default driver — updated_at arrives as a JS Date, so the comparison ran against Sun Aug 30 2026 18:19:25 GMT+0800 (China Standard Time) while the client echoed back the 2026-08-30T10:19:25.947Z its own GET had served. Every guarded save conflicted, on records nobody had touched.

    Why it survived, stated as a coverage fact

    Every existing OCC pin drives ISO text on both sides of the comparison — a memory or mocked engine, or SQLite, all of which round-trip canonical ISO strings. Those pins were green the entire time the production default driver refused every write. The discriminating input is the driver's Date, and nothing in the repo ever produced it into this seam.

    The gap that is still open after the fix

    Temporal Conformance (live PG + MySQL) — the required job where a real Postgres exists — runs pnpm --filter @objectstack/driver-sql test. The OCC seam lives in @objectstack/metadata-protocol, which has no driver dependency and must not grow one (the layering runs the other way). So:

    • the seam's new regression suite pins the behaviour given each input shape, using a hand-made Date — which is correct and sufficient to catch a revert of the repair;
    • but the composed fact that made it a production bug — this driver, against this seam, hands over a Date — is asserted by nothing. It was measured by hand against a real PostgreSQL 16 while fixing the card, and that measurement is not something the repo carries.

    The class is the one AGENTS.md already names elsewhere: a green suite that is not a suite, on the path a double was introduced for.

    Options, for whoever triages this

    1. A driver-side characterisation pin in driver-sql. Assert, under the live matrix, that a row's updated_at read back on Postgres/MySQL is a Date whose String() loses milliseconds and carries the process zone. Cheapest by a wide margin, lands in a package already inside the job, and pins the exact fact the seam's assumption was wrong about. It pins a decision the driver states deliberately (withPostgresCalendarDayAsText: "timestamptz / timestamp are deliberately untouched: those are instants, a Date is the right materialisation for them"), so it is not over-pinning.
    2. An end-to-end OCC cell in the live job, from a package that legitimately depends on both sides (packages/rest and packages/runtime both do). Highest fidelity, but it widens a required job's package set, which is why this is a decision and not a patch.
    3. Accept the gap and rely on the seam-level pins. Defensible; worth recording as a decision rather than leaving it as an accident.

    Recommendation: option 1, and only option 1 unless someone wants the wider cell for its own reasons.

    Wider question this raises, deliberately not answered here

    updated_at is not the only value whose runtime type differs between the Date-returning drivers (Postgres, MySQL, MongoDB) and the ISO-text ones (the SQLite family, memory). Whether other consumers compare or format it while only ever being tested on the text side is a sweep, not a fix, and would be its own card.

    Metadata

    Metadata

    Assignees

    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('^' + ".*" + ' [finding] No live-Postgres coverage of the record-data OCC seam — the driver shape that broke it is only ever a hand-made fixture · Issue #13567 · objectstack-ai/objectstack · GitHub
      Skip to content

      [finding] No live-Postgres coverage of the record-data OCC seam — the driver shape that broke it is only ever a hand-made fixture #13567

      Description

      @zhuangjianguo

      Recording a coverage gap found while fixing #13382. Not a defect in current behaviour#13382's own repair is landed with pins that fail loudly. This is about which backends those pins ever run against, which is a CI-topology decision rather than a bug fix, so it is filed instead of expanded into that PR.

      What #13382 was

      The record-data optimistic-concurrency gate (assertVersionOf / assertVersionMatch in packages/metadata-protocol/src/protocol.ts) compared the record's updated_at against the caller's token with String(v) on both sides. On Postgres — the production default driver — updated_at arrives as a JS Date, so the comparison ran against Sun Aug 30 2026 18:19:25 GMT+0800 (China Standard Time) while the client echoed back the 2026-08-30T10:19:25.947Z its own GET had served. Every guarded save conflicted, on records nobody had touched.

      Why it survived, stated as a coverage fact

      Every existing OCC pin drives ISO text on both sides of the comparison — a memory or mocked engine, or SQLite, all of which round-trip canonical ISO strings. Those pins were green the entire time the production default driver refused every write. The discriminating input is the driver's Date, and nothing in the repo ever produced it into this seam.

      The gap that is still open after the fix

      Temporal Conformance (live PG + MySQL) — the required job where a real Postgres exists — runs pnpm --filter @objectstack/driver-sql test. The OCC seam lives in @objectstack/metadata-protocol, which has no driver dependency and must not grow one (the layering runs the other way). So:

      • the seam's new regression suite pins the behaviour given each input shape, using a hand-made Date — which is correct and sufficient to catch a revert of the repair;
      • but the composed fact that made it a production bug — this driver, against this seam, hands over a Date — is asserted by nothing. It was measured by hand against a real PostgreSQL 16 while fixing the card, and that measurement is not something the repo carries.

      The class is the one AGENTS.md already names elsewhere: a green suite that is not a suite, on the path a double was introduced for.

      Options, for whoever triages this

      1. A driver-side characterisation pin in driver-sql. Assert, under the live matrix, that a row's updated_at read back on Postgres/MySQL is a Date whose String() loses milliseconds and carries the process zone. Cheapest by a wide margin, lands in a package already inside the job, and pins the exact fact the seam's assumption was wrong about. It pins a decision the driver states deliberately (withPostgresCalendarDayAsText: "timestamptz / timestamp are deliberately untouched: those are instants, a Date is the right materialisation for them"), so it is not over-pinning.
      2. An end-to-end OCC cell in the live job, from a package that legitimately depends on both sides (packages/rest and packages/runtime both do). Highest fidelity, but it widens a required job's package set, which is why this is a decision and not a patch.
      3. Accept the gap and rely on the seam-level pins. Defensible; worth recording as a decision rather than leaving it as an accident.

      Recommendation: option 1, and only option 1 unless someone wants the wider cell for its own reasons.

      Wider question this raises, deliberately not answered here

      updated_at is not the only value whose runtime type differs between the Date-returning drivers (Postgres, MySQL, MongoDB) and the ISO-text ones (the SQLite family, memory). Whether other consumers compare or format it while only ever being tested on the text side is a sweep, not a fix, and would be its own card.

      Metadata

      Metadata

      Assignees

      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('^' + ".*" + ' [finding] No live-Postgres coverage of the record-data OCC seam — the driver shape that broke it is only ever a hand-made fixture · Issue #13567 · objectstack-ai/objectstack · GitHub
        Skip to content

        [finding] No live-Postgres coverage of the record-data OCC seam — the driver shape that broke it is only ever a hand-made fixture #13567

        Description

        @zhuangjianguo

        Recording a coverage gap found while fixing #13382. Not a defect in current behaviour#13382's own repair is landed with pins that fail loudly. This is about which backends those pins ever run against, which is a CI-topology decision rather than a bug fix, so it is filed instead of expanded into that PR.

        What #13382 was

        The record-data optimistic-concurrency gate (assertVersionOf / assertVersionMatch in packages/metadata-protocol/src/protocol.ts) compared the record's updated_at against the caller's token with String(v) on both sides. On Postgres — the production default driver — updated_at arrives as a JS Date, so the comparison ran against Sun Aug 30 2026 18:19:25 GMT+0800 (China Standard Time) while the client echoed back the 2026-08-30T10:19:25.947Z its own GET had served. Every guarded save conflicted, on records nobody had touched.

        Why it survived, stated as a coverage fact

        Every existing OCC pin drives ISO text on both sides of the comparison — a memory or mocked engine, or SQLite, all of which round-trip canonical ISO strings. Those pins were green the entire time the production default driver refused every write. The discriminating input is the driver's Date, and nothing in the repo ever produced it into this seam.

        The gap that is still open after the fix

        Temporal Conformance (live PG + MySQL) — the required job where a real Postgres exists — runs pnpm --filter @objectstack/driver-sql test. The OCC seam lives in @objectstack/metadata-protocol, which has no driver dependency and must not grow one (the layering runs the other way). So:

        • the seam's new regression suite pins the behaviour given each input shape, using a hand-made Date — which is correct and sufficient to catch a revert of the repair;
        • but the composed fact that made it a production bug — this driver, against this seam, hands over a Date — is asserted by nothing. It was measured by hand against a real PostgreSQL 16 while fixing the card, and that measurement is not something the repo carries.

        The class is the one AGENTS.md already names elsewhere: a green suite that is not a suite, on the path a double was introduced for.

        Options, for whoever triages this

        1. A driver-side characterisation pin in driver-sql. Assert, under the live matrix, that a row's updated_at read back on Postgres/MySQL is a Date whose String() loses milliseconds and carries the process zone. Cheapest by a wide margin, lands in a package already inside the job, and pins the exact fact the seam's assumption was wrong about. It pins a decision the driver states deliberately (withPostgresCalendarDayAsText: "timestamptz / timestamp are deliberately untouched: those are instants, a Date is the right materialisation for them"), so it is not over-pinning.
        2. An end-to-end OCC cell in the live job, from a package that legitimately depends on both sides (packages/rest and packages/runtime both do). Highest fidelity, but it widens a required job's package set, which is why this is a decision and not a patch.
        3. Accept the gap and rely on the seam-level pins. Defensible; worth recording as a decision rather than leaving it as an accident.

        Recommendation: option 1, and only option 1 unless someone wants the wider cell for its own reasons.

        Wider question this raises, deliberately not answered here

        updated_at is not the only value whose runtime type differs between the Date-returning drivers (Postgres, MySQL, MongoDB) and the ISO-text ones (the SQLite family, memory). Whether other consumers compare or format it while only ever being tested on the text side is a sweep, not a fix, and would be its own card.

        Metadata

        Metadata

        Assignees

        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" + ' [finding] No live-Postgres coverage of the record-data OCC seam — the driver shape that broke it is only ever a hand-made fixture · Issue #13567 · objectstack-ai/objectstack · GitHub
          Skip to content

          [finding] No live-Postgres coverage of the record-data OCC seam — the driver shape that broke it is only ever a hand-made fixture #13567

          Description

          @zhuangjianguo

          Recording a coverage gap found while fixing #13382. Not a defect in current behaviour#13382's own repair is landed with pins that fail loudly. This is about which backends those pins ever run against, which is a CI-topology decision rather than a bug fix, so it is filed instead of expanded into that PR.

          What #13382 was

          The record-data optimistic-concurrency gate (assertVersionOf / assertVersionMatch in packages/metadata-protocol/src/protocol.ts) compared the record's updated_at against the caller's token with String(v) on both sides. On Postgres — the production default driver — updated_at arrives as a JS Date, so the comparison ran against Sun Aug 30 2026 18:19:25 GMT+0800 (China Standard Time) while the client echoed back the 2026-08-30T10:19:25.947Z its own GET had served. Every guarded save conflicted, on records nobody had touched.

          Why it survived, stated as a coverage fact

          Every existing OCC pin drives ISO text on both sides of the comparison — a memory or mocked engine, or SQLite, all of which round-trip canonical ISO strings. Those pins were green the entire time the production default driver refused every write. The discriminating input is the driver's Date, and nothing in the repo ever produced it into this seam.

          The gap that is still open after the fix

          Temporal Conformance (live PG + MySQL) — the required job where a real Postgres exists — runs pnpm --filter @objectstack/driver-sql test. The OCC seam lives in @objectstack/metadata-protocol, which has no driver dependency and must not grow one (the layering runs the other way). So:

          • the seam's new regression suite pins the behaviour given each input shape, using a hand-made Date — which is correct and sufficient to catch a revert of the repair;
          • but the composed fact that made it a production bug — this driver, against this seam, hands over a Date — is asserted by nothing. It was measured by hand against a real PostgreSQL 16 while fixing the card, and that measurement is not something the repo carries.

          The class is the one AGENTS.md already names elsewhere: a green suite that is not a suite, on the path a double was introduced for.

          Options, for whoever triages this

          1. A driver-side characterisation pin in driver-sql. Assert, under the live matrix, that a row's updated_at read back on Postgres/MySQL is a Date whose String() loses milliseconds and carries the process zone. Cheapest by a wide margin, lands in a package already inside the job, and pins the exact fact the seam's assumption was wrong about. It pins a decision the driver states deliberately (withPostgresCalendarDayAsText: "timestamptz / timestamp are deliberately untouched: those are instants, a Date is the right materialisation for them"), so it is not over-pinning.
          2. An end-to-end OCC cell in the live job, from a package that legitimately depends on both sides (packages/rest and packages/runtime both do). Highest fidelity, but it widens a required job's package set, which is why this is a decision and not a patch.
          3. Accept the gap and rely on the seam-level pins. Defensible; worth recording as a decision rather than leaving it as an accident.

          Recommendation: option 1, and only option 1 unless someone wants the wider cell for its own reasons.

          Wider question this raises, deliberately not answered here

          updated_at is not the only value whose runtime type differs between the Date-returning drivers (Postgres, MySQL, MongoDB) and the ISO-text ones (the SQLite family, memory). Whether other consumers compare or format it while only ever being tested on the text side is a sweep, not a fix, and would be its own card.

          Metadata

          Metadata

          Assignees

          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('^' + ".*" + ' [finding] No live-Postgres coverage of the record-data OCC seam — the driver shape that broke it is only ever a hand-made fixture · Issue #13567 · objectstack-ai/objectstack · GitHub
            Skip to content

            [finding] No live-Postgres coverage of the record-data OCC seam — the driver shape that broke it is only ever a hand-made fixture #13567

            Description

            @zhuangjianguo

            Recording a coverage gap found while fixing #13382. Not a defect in current behaviour#13382's own repair is landed with pins that fail loudly. This is about which backends those pins ever run against, which is a CI-topology decision rather than a bug fix, so it is filed instead of expanded into that PR.

            What #13382 was

            The record-data optimistic-concurrency gate (assertVersionOf / assertVersionMatch in packages/metadata-protocol/src/protocol.ts) compared the record's updated_at against the caller's token with String(v) on both sides. On Postgres — the production default driver — updated_at arrives as a JS Date, so the comparison ran against Sun Aug 30 2026 18:19:25 GMT+0800 (China Standard Time) while the client echoed back the 2026-08-30T10:19:25.947Z its own GET had served. Every guarded save conflicted, on records nobody had touched.

            Why it survived, stated as a coverage fact

            Every existing OCC pin drives ISO text on both sides of the comparison — a memory or mocked engine, or SQLite, all of which round-trip canonical ISO strings. Those pins were green the entire time the production default driver refused every write. The discriminating input is the driver's Date, and nothing in the repo ever produced it into this seam.

            The gap that is still open after the fix

            Temporal Conformance (live PG + MySQL) — the required job where a real Postgres exists — runs pnpm --filter @objectstack/driver-sql test. The OCC seam lives in @objectstack/metadata-protocol, which has no driver dependency and must not grow one (the layering runs the other way). So:

            • the seam's new regression suite pins the behaviour given each input shape, using a hand-made Date — which is correct and sufficient to catch a revert of the repair;
            • but the composed fact that made it a production bug — this driver, against this seam, hands over a Date — is asserted by nothing. It was measured by hand against a real PostgreSQL 16 while fixing the card, and that measurement is not something the repo carries.

            The class is the one AGENTS.md already names elsewhere: a green suite that is not a suite, on the path a double was introduced for.

            Options, for whoever triages this

            1. A driver-side characterisation pin in driver-sql. Assert, under the live matrix, that a row's updated_at read back on Postgres/MySQL is a Date whose String() loses milliseconds and carries the process zone. Cheapest by a wide margin, lands in a package already inside the job, and pins the exact fact the seam's assumption was wrong about. It pins a decision the driver states deliberately (withPostgresCalendarDayAsText: "timestamptz / timestamp are deliberately untouched: those are instants, a Date is the right materialisation for them"), so it is not over-pinning.
            2. An end-to-end OCC cell in the live job, from a package that legitimately depends on both sides (packages/rest and packages/runtime both do). Highest fidelity, but it widens a required job's package set, which is why this is a decision and not a patch.
            3. Accept the gap and rely on the seam-level pins. Defensible; worth recording as a decision rather than leaving it as an accident.

            Recommendation: option 1, and only option 1 unless someone wants the wider cell for its own reasons.

            Wider question this raises, deliberately not answered here

            updated_at is not the only value whose runtime type differs between the Date-returning drivers (Postgres, MySQL, MongoDB) and the ISO-text ones (the SQLite family, memory). Whether other consumers compare or format it while only ever being tested on the text side is a sweep, not a fix, and would be its own card.

            Metadata

            Metadata

            Assignees

            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); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' [finding] No live-Postgres coverage of the record-data OCC seam — the driver shape that broke it is only ever a hand-made fixture · Issue #13567 · objectstack-ai/objectstack · GitHub
              Skip to content

              [finding] No live-Postgres coverage of the record-data OCC seam — the driver shape that broke it is only ever a hand-made fixture #13567

              Description

              @zhuangjianguo

              Recording a coverage gap found while fixing #13382. Not a defect in current behaviour#13382's own repair is landed with pins that fail loudly. This is about which backends those pins ever run against, which is a CI-topology decision rather than a bug fix, so it is filed instead of expanded into that PR.

              What #13382 was

              The record-data optimistic-concurrency gate (assertVersionOf / assertVersionMatch in packages/metadata-protocol/src/protocol.ts) compared the record's updated_at against the caller's token with String(v) on both sides. On Postgres — the production default driver — updated_at arrives as a JS Date, so the comparison ran against Sun Aug 30 2026 18:19:25 GMT+0800 (China Standard Time) while the client echoed back the 2026-08-30T10:19:25.947Z its own GET had served. Every guarded save conflicted, on records nobody had touched.

              Why it survived, stated as a coverage fact

              Every existing OCC pin drives ISO text on both sides of the comparison — a memory or mocked engine, or SQLite, all of which round-trip canonical ISO strings. Those pins were green the entire time the production default driver refused every write. The discriminating input is the driver's Date, and nothing in the repo ever produced it into this seam.

              The gap that is still open after the fix

              Temporal Conformance (live PG + MySQL) — the required job where a real Postgres exists — runs pnpm --filter @objectstack/driver-sql test. The OCC seam lives in @objectstack/metadata-protocol, which has no driver dependency and must not grow one (the layering runs the other way). So:

              • the seam's new regression suite pins the behaviour given each input shape, using a hand-made Date — which is correct and sufficient to catch a revert of the repair;
              • but the composed fact that made it a production bug — this driver, against this seam, hands over a Date — is asserted by nothing. It was measured by hand against a real PostgreSQL 16 while fixing the card, and that measurement is not something the repo carries.

              The class is the one AGENTS.md already names elsewhere: a green suite that is not a suite, on the path a double was introduced for.

              Options, for whoever triages this

              1. A driver-side characterisation pin in driver-sql. Assert, under the live matrix, that a row's updated_at read back on Postgres/MySQL is a Date whose String() loses milliseconds and carries the process zone. Cheapest by a wide margin, lands in a package already inside the job, and pins the exact fact the seam's assumption was wrong about. It pins a decision the driver states deliberately (withPostgresCalendarDayAsText: "timestamptz / timestamp are deliberately untouched: those are instants, a Date is the right materialisation for them"), so it is not over-pinning.
              2. An end-to-end OCC cell in the live job, from a package that legitimately depends on both sides (packages/rest and packages/runtime both do). Highest fidelity, but it widens a required job's package set, which is why this is a decision and not a patch.
              3. Accept the gap and rely on the seam-level pins. Defensible; worth recording as a decision rather than leaving it as an accident.

              Recommendation: option 1, and only option 1 unless someone wants the wider cell for its own reasons.

              Wider question this raises, deliberately not answered here

              updated_at is not the only value whose runtime type differs between the Date-returning drivers (Postgres, MySQL, MongoDB) and the ISO-text ones (the SQLite family, memory). Whether other consumers compare or format it while only ever being tested on the text side is a sweep, not a fix, and would be its own card.

              Metadata

              Metadata

              Assignees

              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)) { // 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); } })(); })(); [finding] No live-Postgres coverage of the record-data OCC seam — the driver shape that broke it is only ever a hand-made fixture · Issue #13567 · objectstack-ai/objectstack · GitHub
                Skip to content

                [finding] No live-Postgres coverage of the record-data OCC seam — the driver shape that broke it is only ever a hand-made fixture #13567

                Description

                @zhuangjianguo

                Recording a coverage gap found while fixing #13382. Not a defect in current behaviour#13382's own repair is landed with pins that fail loudly. This is about which backends those pins ever run against, which is a CI-topology decision rather than a bug fix, so it is filed instead of expanded into that PR.

                What #13382 was

                The record-data optimistic-concurrency gate (assertVersionOf / assertVersionMatch in packages/metadata-protocol/src/protocol.ts) compared the record's updated_at against the caller's token with String(v) on both sides. On Postgres — the production default driver — updated_at arrives as a JS Date, so the comparison ran against Sun Aug 30 2026 18:19:25 GMT+0800 (China Standard Time) while the client echoed back the 2026-08-30T10:19:25.947Z its own GET had served. Every guarded save conflicted, on records nobody had touched.

                Why it survived, stated as a coverage fact

                Every existing OCC pin drives ISO text on both sides of the comparison — a memory or mocked engine, or SQLite, all of which round-trip canonical ISO strings. Those pins were green the entire time the production default driver refused every write. The discriminating input is the driver's Date, and nothing in the repo ever produced it into this seam.

                The gap that is still open after the fix

                Temporal Conformance (live PG + MySQL) — the required job where a real Postgres exists — runs pnpm --filter @objectstack/driver-sql test. The OCC seam lives in @objectstack/metadata-protocol, which has no driver dependency and must not grow one (the layering runs the other way). So:

                • the seam's new regression suite pins the behaviour given each input shape, using a hand-made Date — which is correct and sufficient to catch a revert of the repair;
                • but the composed fact that made it a production bug — this driver, against this seam, hands over a Date — is asserted by nothing. It was measured by hand against a real PostgreSQL 16 while fixing the card, and that measurement is not something the repo carries.

                The class is the one AGENTS.md already names elsewhere: a green suite that is not a suite, on the path a double was introduced for.

                Options, for whoever triages this

                1. A driver-side characterisation pin in driver-sql. Assert, under the live matrix, that a row's updated_at read back on Postgres/MySQL is a Date whose String() loses milliseconds and carries the process zone. Cheapest by a wide margin, lands in a package already inside the job, and pins the exact fact the seam's assumption was wrong about. It pins a decision the driver states deliberately (withPostgresCalendarDayAsText: "timestamptz / timestamp are deliberately untouched: those are instants, a Date is the right materialisation for them"), so it is not over-pinning.
                2. An end-to-end OCC cell in the live job, from a package that legitimately depends on both sides (packages/rest and packages/runtime both do). Highest fidelity, but it widens a required job's package set, which is why this is a decision and not a patch.
                3. Accept the gap and rely on the seam-level pins. Defensible; worth recording as a decision rather than leaving it as an accident.

                Recommendation: option 1, and only option 1 unless someone wants the wider cell for its own reasons.

                Wider question this raises, deliberately not answered here

                updated_at is not the only value whose runtime type differs between the Date-returning drivers (Postgres, MySQL, MongoDB) and the ISO-text ones (the SQLite family, memory). Whether other consumers compare or format it while only ever being tested on the text side is a sweep, not a fix, and would be its own card.

                Metadata

                Metadata

                Assignees

                Type

                No type

                Projects

                No projects

                  Milestone

                  No milestone

                  Relationships

                  None yet

                  Development

                  No branches or pull requests

                  Issue actions