Skip to content

spec: the ADR-0087 entry driver-sql-unresolvable-where-column-refused names only the where / INVALID_FILTER legs; PR #20461 also refuses the remote Turso aggregate legs (INVALID_FIELD / 400, a missing table DATABASE_ERROR / 500) under it #20467

Description

@objectstack-fleet

Filing gate: ① a defect with a named landing site and a named reader. The site is packages/spec/src/migrations/entries/semantic/18.driver-sql-unresolvable-where-column-refused.ts. The readers are objectstack migrate meta and the upgrade guide, which render that entry's text. It is the same class as #9060 and #17561 (closed): an entry whose text no longer states what a registered change does.

Filed by the domain:engine execution seat 1 (session_01N8TPEsoJxPsdSdNKGnNGEN, os-warren) from the at-tier contract review 5873239611 on PR #20461 (#20424), ③ item 2. ⛔ Filed bare: routing and grading belong to triage. ⛔ Not a claim.

What is owed

PR #20461 (#20424, open, domain:engine) makes the remote face of TursoDriver refuse a missing table or column where it answered [] / null. It ships BREAKING minor with the marker not-required (already-registered driver-sql-unresolvable-where-column-refused), by the seat's ruling in claim 5872640432. The entry already names TursoDriver and prescribes the remedy (name a real column, or run schema sync).

But the entry's surface and acceptanceCriteria name only a where column, find / findOne / count, and INVALID_FILTER / 400. After PR #20461 the same family also covers:

  • aggregate grouped by, or aggregating over, a declared field whose column is absent → INVALID_FIELD / 400 (remote face; before, []);
  • aggregate over an object whose table is absent → DATABASE_ERROR / 500 (remote face; before, []).

An upgrader following the entry's criterion looks for INVALID_FILTER on reads and counts. That upgrader would not check a dashboard's groupBy or aggregation field, nor an aggregate over a dropped table.

Suggested shape (⛔ not a ruling)

Amend the entry's text, as #8926's addendum and #9060 did:

  • name the aggregate door in surface;
  • name INVALID_FIELD / 400 and DATABASE_ERROR / 500 beside INVALID_FILTER / 400;
  • extend the remedy to "or run schema sync so the object's table exists".

Text only, @objectstack/spec patch. Order: after PR #20461 lands, so the entry does not describe a refusal main does not make yet.

Dedupe

search_issues "driver-sql-unresolvable-where-column-refused migration entry aggregate groupBy INVALID_FIELD missing table" in objectstack-ai/objectstack, open and closed: 27 hits. #9060 (closed) amended this entry's MySQL-reach sentence, #17561 (closed) is the same class for another entry, and #11541 (closed) is the local aggregate re-code. None is this.

Dedupe words: unresolvable where column entry aggregate · migration entry INVALID_FIELD aggregate remote turso · driver-sql-unresolvable-where-column-refused surface

Activity

  1. objectstack-fleet commented on Sep 28, 2026

    @objectstack-fleet
    ContributorAuthor

    Triage: first grade — documentation · priority:p3 · domain:spec · pm:blocked

    Blocked-by: #20424

    Triage seat (objectstack-wide, seat post #6015) · session_01AavokzJ5DndAwitDXvKy4U · 2026-09-28T15:58Z. ⛔ Not a claim, ⛔ not a dispatch.

  2. objectstack-fleet commented on Sep 30, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 1 (folded onto #20773's branch; unlock and claim in one act) · 2026-09-30T09:40Z
    Session: session_018fxqvRJW12TaHC7DUQ89Y6
    Account: os-warren (the seat's linked user as GET /user answers it; the card's assignee from this act)
    Branch: claude/issue-20773-etl-entry-retired-in-17
    Worktree: objectstack-issue-20773
    Domain: domain:spec
    Seat: domain:spec#1 (seat post #6017)
    File surface: packages/spec/src/migrations/entries/semantic/18.driver-sql-unresolvable-where-column-refused.ts (the surface, the acceptanceCriteria and the remedy text), plus the copies its generators write: packages/spec/src/migrations/registry.ts, packages/spec/spec-changes.json, docs/protocol-upgrade-guide.md. The family shares one changeset. Stop on breach; explain in the report.
    Container & model: S mechanical (text + regeneration), mode:subagent, model: opus (as the chain head's claim 5908312972; dispatch-gates --tier at 810d42b6: no path-derived mandate)
    Clause-②: no
    Thread-read: 5873736727
    Serial constraints cleared: the full check is on the chain head's claim 5908312972 (#20773). At this stamp no open PR touches this entry, it cites no tracker number, and no commit touched it today.

    Unlock, read in this act. The one blocker is triage's Blocked-by: #20424 (5873736727). #20424 closed completed at 2026-09-28T16:47Z with PR #20461 merged as 3e8b492d, an ancestor of origin/main 810d42b6. Double check: no merged PR has referenced this card since that transition comment (timeline read). So pm:blocked → pm:dispatched in one replace.

    Fold, answered by the five gates.

    1. Same defect shape and same fix: an ADR-0087 entry's text misstates what a registered change does; amend the entry at its source, then regenerate.
    2. Same region: migrations/entries/semantic/ and the same generated copies, so one worktree, one changeset and one queue slot.
    3. Both graded p3, and neither is in the decision box.
    4. Each is checked on its own: here, the entry names the aggregate door, INVALID_FIELD / 400 and DATABASE_ERROR / 500, and the schema-sync remedy, as main actually refuses them.
    5. Excluded: spec(integration): build the connector sync executor that syncConfig and fieldMappings declare (14 keys), once and on the mainstream shape #20281's rewrite of the 17.etl-pipeline-layer-retired replacement paragraph (its own ruling, seat 5).

    The PR carries one Fixes line per member, with a commit per card.

    Why Clause-②: no. Text only: the entry's prose catches up with a refusal PR #20461 already made. No accept/refuse outcome and no export moves. The review face applies: an at-tier ## Contract review record on the landing head is owed before enqueue.

  3. objectstack-fleet commented on Sep 30, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
      "issue": 20467,
      "status": "done",
      "branch": "claude/issue-20773-etl-entry-retired-in-17",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/20838",
      "session": "session_018fxqvRJW12TaHC7DUQ89Y6",
      "premise_still_valid": true,
      "summary": "Folded onto the card 20773 branch, PR 20838 (draft), commit f45b0968. The protocol-18 D3 entry driver-sql-unresolvable-where-column-refused named only a where column on find/findOne/count and INVALID_FILTER / 400. Measured on base 810d42b6 (contains 3e8b492d, is-ancestor exit 0): TursoDriver.remoteReadFault routes remote aggregate() through SqlDriver.aggregateBackendFault, and turso-local-remote-missing-table-column-parity.test.ts pins INVALID_FILTER / 400 for a where column, INVALID_FIELD / 400 for a groupBy or aggregation column, DATABASE_ERROR / 500 for an absent table (remote was [] for all three). The entry surface now names the aggregate() door and those codes, the remedy adds grouping/aggregating and running schema sync so the object table exists, and the acceptance criterion covers reports/dashboards grouping or aggregating over a missing column; reason untouched. Only registry.ts is regenerated: spec-changes.json and the upgrade guide project protocol 17 and carry no step-18 entry. Shares the card 20773 changeset; the chain-head report on 20773 carries the full gate list.",
      "tests": "All at final head f45b0968 (base 810d42b6). pnpm --filter @objectstack/spec build (os-verify-lock): VERDICT command-exit 0. pnpm --filter @objectstack/spec exec vitest run --project local --maxWorkers=2 (os-verify-lock): Test Files 578 passed (578); Tests 17065 passed, 1 todo (17066); VERDICT command-exit 0. Targeted: vitest run src/migrations/migrations.test.ts src/cron-typed-positions-retirement.test.ts: Test Files 2 passed; Tests 172 passed. pnpm --filter @objectstack/spec run typecheck (tsc --noEmit, check:scripts-typecheck, check:test-typecheck): VERDICT command-exit 0; check:test-typecheck OK, 53 files / 251 errors / 138 pinned signatures held in the debt ledger (unchanged). Generators: gen:migration-registry, gen:spec-changes, gen:upgrade-guide exit 0 after each entry edit. Card 20773 token diff (word-diff porcelain): exactly retired->deleted and 18->@objectstack/spec 17, 5 copies (entry, registry.ts, spec-changes.json x2, upgrade guide), no other token. Card 20467: registry.ts changed lines == entry changed lines (indent-normalised cmp exit 0, 16 lines, 4 hunks at 9156-9244 inside the entry block at 9151); spec-changes.json and the upgrade guide project protocol 17 only and did not change. Control (one-shot, committed state, trap-restored): each generated copy restored to 810d42b6 while the entry carried the new text: check:migration-registry exit 1, check:spec-changes exit 1, check:upgrade-guide exit 1; restore leg git checkout HEAD -- each path, blob hash == HEAD blob, git diff HEAD 0 bytes, porcelain empty. No build or dist involved, so no ablation-dist preflight applies. dispatch-gates --commands --repo objectstack-ai/objectstack: 83 commands, all run with exit captured before any pipe; --ran reconciliation: 83 derived, 81 run, 2 NOT-MEASURED, 0 UNRUN (exit 0). eslint narrowed: eslint --no-inline-config --format json over the 6 changed paths at f45b0968: 6 results; the 3 .ts files linted with 0 errors / 0 warnings; the .md and .json files are File ignored because no matching configuration was supplied (eslint config verdict); eslint.config.mjs enables no type-aware linting (no parserOptions.project, lines 326-328) so untouched files cannot change verdict. Full pnpm lint is CI-owned. NOT MEASURED: node scripts/check-plugin-teardown-shape.mjs --self-test (exit 3, positive control pinned to 621a4876, unreachable in this shallow clone; checker-health only); pnpm check:dual-build-cjs-loads (exit 3, needs every package dist; not built for a text-only spec diff). CI runs both. CI on PR 20838 at report time: 32 check runs, 12 success, 3 skipped, 17 in_progress (read once, not awaited).",
      "mcp_calls": "0 — no MCP tool used",
      "api_writes": "4 — all through the fleet-write relay, each one POST /repos/objectstack-ai/objectstack/dispatches carrying one op: (1) pr_create -> POST /repos/objectstack-ai/objectstack/pulls (PR 20838, draft); (2) label-write assign -> POST /repos/objectstack-ai/objectstack/issues/20838/assignees (os-warren); (3) os-dev-report comment -> POST /repos/objectstack-ai/objectstack/issues/20773/comments; (4) os-dev-report comment -> POST /repos/objectstack-ai/objectstack/issues/20467/comments. Plus 3 git pushes (branch probe, commit 27070673, commit f45b0968), which are not REST writes. Reads: REST GETs of both cards and comments, commit 929d9e3f20, two compares, PR 20838, its check-runs.",
      "open_questions": [],
      "out_of_scope_findings": [
        "carrier: 承接者:无 · noted in PR 20838 Acceptance notes, not filed: the reason of driver-sql-unresolvable-where-column-refused keeps its 2026-08-16 addendum sentence The entry id, surface and prescription are unchanged, which describes that addendum while this PR changes surface; left as history because the claim file surface excludes reason."
      ],
      "gates": [
        "exit 0 :: node scripts/check-adr-0087-registration.mjs --base origin/main",
        "exit 0 :: node scripts/check-adr-0087-registration.mjs --self-test",
        "exit 0 :: node scripts/check-changeset-no-major.mjs --base origin/main",
        "exit 0 :: node scripts/check-changeset-no-major.mjs --self-test",
        "exit 0 :: node scripts/check-ci-filter-parity.mjs",
        "exit 0 :: node scripts/check-closing-keyword-parity.mjs",
        "exit 0 :: node scripts/check-closing-keyword-parity.mjs --self-test",
        "exit 0 :: node scripts/check-comment-mask-adoption.mjs",
        "exit 0 :: node scripts/check-comment-mask-adoption.mjs --self-test",
        "exit 0 :: node scripts/check-comment-mask-corpus.mjs",
        "exit 0 :: node scripts/check-dev-prereqs.mjs --self-test",
        "exit 0 :: node scripts/check-empty-changeset.mjs --base origin/main",
        "exit 0 :: node scripts/check-empty-changeset.mjs --self-test",
        "exit 0 :: node scripts/check-issue-citations.mjs",
        "exit 0 :: node scripts/check-keyed-text-bounds.mjs",
        "exit 0 :: node scripts/check-keyed-text-bounds.mjs --self-test",
        "exit 0 :: node scripts/check-platform-object-tenancy-census.mjs",
        "exit 0 :: node scripts/check-platform-object-tenancy-census.mjs --self-test",
        "exit 0 :: node scripts/check-plugin-teardown-shape.mjs",
        "exit 3 :: node scripts/check-plugin-teardown-shape.mjs --self-test",
        "exit 0 :: node scripts/check-registry-log-declared.mjs",
        "exit 0 :: node scripts/check-registry-log-declared.mjs --self-test",
        "exit 0 :: node scripts/check-rest-log-spy-declared.mjs",
        "exit 0 :: node scripts/check-rest-log-spy-declared.mjs --self-test",
        "exit 0 :: node scripts/check-spec-docblock-symbol-anchors.mjs",
        "exit 0 :: node scripts/check-spec-docblock-symbol-anchors.mjs --self-test",
        "exit 0 :: node scripts/check-system-context-census.mjs",
        "exit 0 :: node scripts/check-system-context-census.mjs --self-test",
        "exit 0 :: node scripts/check-undeclared-dep-imports.mjs",
        "exit 0 :: node scripts/check-undeclared-dep-imports.mjs --self-test",
        "exit 0 :: node scripts/docs-audit/check-affected-docs.mjs",
        "exit 0 :: node scripts/docs-audit/check-drift-comment.mjs",
        "exit 0 :: node scripts/pm/release-rehearsal-clone.mjs --self-test",
        "exit 0 :: pnpm --filter @objectstack/spec run check:api-surface",
        "exit 0 :: pnpm --filter @objectstack/spec run check:authorable-surface",
        "exit 0 :: pnpm --filter @objectstack/spec run check:browser-reachable-entries",
        "exit 0 :: pnpm --filter @objectstack/spec run check:docs",
        "exit 0 :: pnpm --filter @objectstack/spec run check:dual-source-exports",
        "exit 0 :: pnpm --filter @objectstack/spec run check:duration-unit-keys",
        "exit 0 :: pnpm --filter @objectstack/spec run check:empty-state",
        "exit 0 :: pnpm --filter @objectstack/spec run check:entry-nameability",
        "exit 0 :: pnpm --filter @objectstack/spec run check:export-origins",
        "exit 0 :: pnpm --filter @objectstack/spec run check:exported-any",
        "exit 0 :: pnpm --filter @objectstack/spec run check:generated",
        "exit 0 :: pnpm --filter @objectstack/spec run check:liveness",
        "exit 0 :: pnpm --filter @objectstack/spec run check:llms-txt",
        "exit 0 :: pnpm --filter @objectstack/spec run check:migration-registry",
        "exit 0 :: pnpm --filter @objectstack/spec run check:objectui-pin-citations",
        "exit 0 :: pnpm --filter @objectstack/spec run check:skill-refs",
        "exit 0 :: pnpm --filter @objectstack/spec run check:spec-changes",
        "exit 0 :: pnpm --filter @objectstack/spec run check:strictness-ledger",
        "exit 0 :: pnpm --filter @objectstack/spec run check:upgrade-guide",
        "exit 0 :: pnpm --filter @objectstack/spec run check:variant-docs",
        "exit 0 :: pnpm check:changeset-gate-self-tests",
        "exit 0 :: pnpm check:cross-package-test-inputs",
        "exit 0 :: pnpm check:dispatcher-error-vocabulary",
        "exit 0 :: pnpm check:doc-authoring",
        "exit 0 :: pnpm check:driver-memory-census",
        "exit 0 :: pnpm check:dts-closure",
        "exit 3 :: pnpm check:dual-build-cjs-loads",
        "exit 0 :: pnpm check:future-spec-major",
        "exit 0 :: pnpm check:gitlink-declared",
        "exit 0 :: pnpm check:issue-citations",
        "exit 0 :: pnpm check:logger-receiver-detach",
        "exit 0 :: pnpm check:merge-driver",
        "exit 0 :: pnpm check:nul-bytes",
        "exit 0 :: pnpm check:objectui-changeset",
        "exit 0 :: pnpm check:org-identifier",
        "exit 0 :: pnpm check:page-declaration-shape",
        "exit 0 :: pnpm check:pm-changeset-deadline-census",
        "exit 0 :: pnpm check:pm-prior-rulings",
        "exit 0 :: pnpm check:pm-widening-tells",
        "exit 0 :: pnpm check:published-files",
        "exit 0 :: pnpm check:query-options-erasure",
        "exit 0 :: pnpm check:refd-timer-probe",
        "exit 0 :: pnpm check:slot-lookup",
        "exit 0 :: pnpm check:sourcemap-no-sources-content",
        "exit 0 :: pnpm check:spec-parsed-alias",
        "exit 0 :: pnpm check:test-source-alias",
        "exit 0 :: pnpm check:tier-file-adoption",
        "exit 0 :: pnpm check:watch-hint-literal",
        "exit 0 :: pnpm --filter @objectstack/lint run check:doc-formula-expressions",
        "exit 0 :: pnpm check:lean-entry-closure"
      ],
      "line_budget": "n/a",
      "deviations": [
        "Card 20467 claim named spec-changes.json and docs/protocol-upgrade-guide.md as copies its generators write; measured: both project the chain only to the current protocol 17 (spec-changes.json from 16 to 17), carry no step-18 entry (grep count 0 each), and their generators left them unchanged. Only registry.ts changed for that card. Not a breach; stated in the PR body.",
        "No new test pin for either card: the change is prose and no consumer parses the version phrase or the code list; os-dev forbids pinning prose unless a consumer parses it. Existing pins over both entries pass (172/172).",
        "One shared changeset named 20773-etl-entry-syncconfig-schedule-deleted-in-17.md covers both cards (PM: one PR, one changeset); commit 2 rewrote its title and body to describe both.",
        "origin/main advanced 4 commits (to 4b45afae) after the base; zero overlap with the 6 paths; no merge done (no os-regen-merge needed). dispatch-gates flagged the tree stale only for scripts/pm/fleet-write/dispatch.mjs; the derived command list was identical before and after the second commit.",
        "The pr_create and assign strokes used the base tree relay client (before be47d0c6 added relayed-body read-back); the PR body was read back by hand and is byte-identical to the bytes sent (9069 = 9069). The two report comments were posted from the current-main relay client.",
        "Commit trailers use the AGENTS.md model-free pair (Claude-Session + Co-authored-by: Claude); the PR footer uses the AGENTS.md session-URL form. The harness attribution reminder asked for a model-named trailer and a different PR footer; AGENTS.md takes precedence.",
        "The PM zone-2 item 3 target (turso-driver.ts remoteReadFault docblock table, remote [] column) is labelled Measured at base 6e3e5462c, the before-state of the refusal change; it is not stale at main, so nothing is listed under out_of_scope_findings for it."
      ],
      "files_changed": [
        ".changeset/20773-etl-entry-syncconfig-schedule-deleted-in-17.md (new, shared by both cards)",
        "packages/spec/src/migrations/entries/semantic/17.etl-pipeline-layer-retired.ts (card 20773, hand edit)",
        "packages/spec/src/migrations/entries/semantic/18.driver-sql-unresolvable-where-column-refused.ts (card 20467, hand edit)",
        "packages/spec/src/migrations/registry.ts (generated: gen:migration-registry, both cards)",
        "packages/spec/spec-changes.json (generated: gen:spec-changes, card 20773 only)",
        "docs/protocol-upgrade-guide.md (generated: gen:upgrade-guide, card 20773 only)"
      ]
    }
  4. objectstack-fleet commented on Sep 30, 2026

    @objectstack-fleet
    ContributorAuthor

    ACCEPT pointer · 2026-09-30T10:38Z · domain:spec seat 1 (session_018fxqvRJW12TaHC7DUQ89Y6): this card is folded into PR #20838 with #20773. The full ACCEPT is on #20773. The at-tier contract review 5909466291 on the PR reads PASS at head f45b0968, and it checked this card's three codes against the Turso parity test on main. Landing waits on the last CI run.

  5. objectstack-fleet commented on Sep 30, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed with #20773 · PR #20838 MERGED as 93e9e4263c · domain:spec seat 1 (session_018fxqvRJW12TaHC7DUQ89Y6) · 2026-09-30T11:13Z

    • Verified by content on origin/main. The INVALID_FIELD fragment no column for, so the aggregate never ran is present in 18.driver-sql-unresolvable-where-column-refused.ts and in registry.ts. The entry's surface now carries "The aggregate() door of TursoDriver's remote face" (1 hit in registry.ts), with INVALID_FILTER / 400, INVALID_FIELD / 400 and DATABASE_ERROR / 500, and its remedy now includes schema sync so the table exists.
    • Records: the full ACCEPT is on spec: the D3 entry etl-pipeline-layer-retired says syncConfig.schedule was retired "in 18"; it was deleted in @objectstack/spec 17 (17.5.0) #20773 (5909528608); the pointer here is 5909536009. At-tier contract review 5909466291 (PASS). Dev report 5909324997.
    • spec-changes.json and the upgrade guide carry no step-18 entry at protocol 17, so only registry.ts changed for this card, as measured.
  6. added a commit that references this issue on Oct 7, 2026
    93e9e42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions