Skip to content

test doubles: a limit-blind ObjectQL find double in a plugin-sharing testkit sits outside both double gates, which walk *.test.ts only #28608

Closed

Description

@objectstack-fleet

domain:server#1 · os-project-manager · session_01R1q2xdtYgU6FKrZ7LgjPCC

Filing gate: ① out-of-scope finding of the #23181 slice 30 dev (os-dev-report 6555141723 on #23181), measured by a probe that was restored. Filed by domain:server seat 1. ⛔ Not a claim. No grade: triage sets the lane and grade.

What was measured. Both gates that hold test doubles to the real engine's contract discover doubles only in test files:

  • scripts/check-engine-double-contract.mjs walk() admits /\.(test|spec)\.(ts|tsx|mts)$/.
  • scripts/check-objectql-double-limit.mjs testFilesUnder() admits /\.test\.ts$/.

The repo keeps 62 shared kits under __tests__/*.testkit.ts (and similar), which neither gate reads. With both walks widened to *.testkit.ts (probe only, not committed; output in pm-orders/server/evidence/23181-s30/odl-widen.log), check:objectql-double-limit reports:

packages/plugins/plugin-sharing/src/exec-context-seam.testkit.ts: NEW ObjectQL find double that does not hold the caller's bound (1 blind, 0 breaking a shape rule, 0 unjudged). line 58: BLIND

So one limit-blind find double is live today outside the gate meant to catch it.

Two questions for triage.

  1. The plugin-sharing double: make it hold limit by presence (or throw on a bound it does not implement), as the gate's own advice says.
  2. Whether the two double gates should also walk testkit files. That widens what two existing gates enforce, so it is not a seat call (「新增门禁默认否」). The slice 30 report's option A measured the cost: one regex in check-engine-double-contract (rows move cleanly with --write), and in check-objectql-double-limit the regex, ROOT_DIR_WATCH_HINTS and its --self-test DECLARED_TAIL pin, plus paying any limit debt the widened walk surfaces (the baseline only shrinks).

Not affected by this card. Slice 30 is re-ordered to keep plugin-auth's shared double in its .test.ts file (seat ruling on #23181), so nothing there leaves either gate's sight.


Generated by Claude Code

Activity

  1. added
    findingRecorded observation — held, not dispatchable until the findings triage round grades it
    domain:serverDomain lane — seat card indexed by label:pm:seat
    on Nov 1, 2026
  2. objectstack-fleet commented on Nov 1, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#1 · os-project-manager · session_01R1q2xdtYgU6FKrZ7LgjPCC

    Triage: p3 · domain:server · pm:queue · 2026-11-01T12:15Z

    Ruling-ref: 「定级你可以自己决定」 (Leehom, 2026-11-01T12:11Z), which lets the server seats grade this lane's cards; the grading was split between seats 1, 2 and 3 in advance. ⛔ Not a claim.

    • Question 1, the plugin-sharing double: p3, graded in. makeSeamQl().find in packages/plugins/plugin-sharing/src/exec-context-seam.testkit.ts (about line 58) filters on where and ignores limit. Five plugin-sharing files import it, so a caller's bound is silently dropped wherever a test runs through the seam. It is a test-double fidelity defect with no production reach, hence p3.
      • Fix: hold limit by presence (slice the filtered rows), or throw on a bound it does not implement, as the gate's own advice says.
      • Red first: a case that passes limit: 1 over two matching rows, on the base double.
    • Question 2, whether both double gates should walk *.testkit.ts: graded out, not this card. Widening what two existing gates enforce is a gate addition in effect, and under 「新增门禁默认否」 that needs the maintainer to name it. Without that, the answer is "do not add". The probe log stays in pm-orders/server/evidence/23181-s30/odl-widen.log as the measured cost if the maintainer asks for it.
    • bug, priority:p3, pm:queue.

    Generated by Claude Code

  3. objectstack-fleet commented on Nov 1, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#1 · os-project-manager · session_01R1q2xdtYgU6FKrZ7LgjPCC

    Claim: PM loop round 1 · card thread · 2026-11-01T12:20Z
    Session: session_01R1q2xdtYgU6FKrZ7LgjPCC (the seat); the card thread is session_01FEkQ5kA7pasGpR4Pf7mtNb
    Account: os-project-manager (the seat's linked user; the card's assignee)
    Branch: claude/project-thread-qk6ezf (the card thread's harness-pinned branch; it names no issue, so this claim is the identity record)
    Worktree: the card thread's own container checkout
    Domain: domain:server
    Seat: domain:server#1
    Ruling-ref: triage record 6557807357 (p3, question 1 only), graded under 「定级你可以自己决定」 (2026-11-01T12:11Z); p3 dispatch under 「server 车道现在就是你负责,任务有一大堆啊,都可以派,包括 p3」 (2026-11-01T03:46Z). Server seats 2 and 3 were told before this claim.
    File surface: packages/plugins/plugin-sharing/src/exec-context-seam.testkit.ts (makeSeamQl().find holds limit) and one plugin-sharing test for it. ⛔ No edit to scripts/check-engine-double-contract.mjs or scripts/check-objectql-double-limit.mjs.
    Container & model: S, mode:thread, model and effort as the thread was opened
    Clause-②: no (expected: a test double only)
    Metadata-protocol: none (expected)
    Responsibility: the code is plugin-sharing's shared test seam · no platform path (test-only) · reached by the five plugin-sharing test files that import the seam
    Thread-read: none
    Premise: holds (read 2026-11-01T12:20Z at origin/main 0b6a52e8a0: makeSeamQl().find filters where and never reads opts.limit)
    Serial constraints cleared: no open PR touches packages/plugins/plugin-sharing/src/
    Resume-from: none — fresh from origin/main 0b6a52e8a0

    State: pm:queue → pm:dispatched, assigned to os-project-manager, recorded by this claim.


    Generated by Claude Code

  4. added
    pm:dispatchedDispatched to a dev agent by /pm-dispatch
    and removed
    pm:queueReady for the PM dispatch loop
    on Nov 1, 2026
  5. objectstack-fleet commented on Nov 1, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#1 · os-project-manager · session_01FEkQ5kA7pasGpR4Pf7mtNb

    os-dev-report
    {
    "issue": 28608,
    "status": "done",
    "branch": "claude/project-thread-qk6ezf",
    "pr": "#28670",
    "session": "session_01FEkQ5kA7pasGpR4Pf7mtNb",
    "premise_still_valid": true,
    "summary": "makeSeamQl().find in packages/plugins/plugin-sharing/src/exec-context-seam.testkit.ts now slices the where-filtered rows to the caller's limit by presence (typeof opts?.limit === 'number'), the first shape check-objectql-double-limit.mjs prescribes. Slicing was picked over throwing because resolveAuthzContext reads through this double with real bounds (limit 1, 2, 200 and others), so a throwing double would break every importer. where handling is unchanged; makeSeamQl is exported only for its new pin exec-context-seam.limit.test.ts. Neither gate script is touched (question 2 out). Importer count measured: 3 test files import the seam plus 1 type-only import (exec-context-annotation.pin.ts), not five; all pass unchanged. No PR assignee and no PR subscription, per the order.",
    "tests": "Red first (export only, fix absent): exec-context-seam.limit.test.ts 'answers at most limit rows when more match' fails, expected [ Array(2) ] to deeply equal [ { id: 'a', …(1) } ], Tests 1 failed | 2 passed (3). Green on fix: Tests 3 passed (3). Ablation via scripts/ablation-replace.mjs: limit line replaced by 'return matched;' (anchor x1 -> x0, blob d27c845e10d6 -> 17d1ac7833f6), same case red (1 failed | 2 passed), restore: blob after restore == HEAD blob d27c845e10d6, git diff HEAD empty; testkit is source imported relatively, no dist leg. Whole suite on head e410091 under the lock: pnpm --filter @objectstack/plugin-sharing test, VERDICT command-exit 0, Test Files 59 passed (59), Tests 1299 passed (1299). pnpm --filter @objectstack/plugin-sharing typecheck VERDICT command-exit 0. eslint --no-inline-config packages/plugins/plugin-sharing exit 0. Gate-walk probe (copy of check-objectql-double-limit.mjs with testFilesUnder widened to (test|testkit).ts, never committed, deleted): head exit 0 'OK ... 643 double(s) graded', no plugin-sharing row; base testkit blob exit 1 'exec-context-seam.testkit.ts ... (1 blind ...) line 58: BLIND'; restore proven by blob equality and empty git diff HEAD.",
    "gates": "Local subset on head e410091 from dispatch-gates.mjs --commands --repo objectstack-ai/objectstack (52 derived). 51 exit 0, incl. check:objectql-double-limit, check:engine-double-contract, check:where-matcher, check:query-options-erasure, check:test-source-alias, check:type-check-debt, check:published-files, check:nul-bytes. check-plugin-teardown-shape.mjs --self-test exit 3 (shallow) then exit 0 after fetching fixture 621a487. check:i18n exit 3 (CLI unbuilt) then exit 0 after its prerequisite build. check:dual-build-cjs-loads exit 3 PREREQUISITE NOT MET = NOT MEASURED (needs every package dist), CI runs it. --ran: '52 derived famil(ies) accounted for — 51 run, 1 NOT-MEASURED', exit 0. Record: pm-orders/server/28608-gates-ran.txt. PR check-runs: in_progress at report time (not waited on).",
    "dogfood_battery": "n/a — no ! in the PR title and no (narrowing) arm",
    "mcp_calls": "4 — reads only: issue_read get, issue_read get_comments x2, pull_request_read get",
    "api_writes": "2 — POST /repos/objectstack-ai/objectstack/dispatches (relay pr_create with labels skip-changeset, run 41308407869 success, PR #28670 body read back identical, assignees none), and this os-dev-report comment via post-stamped.mjs; plus git push (not REST)",
    "open_questions": [],
    "out_of_scope_findings": [
    "none — the widened-walk probe on head shows no other testkit double red; the probe log row for plugin-auth memory-engine.testkit.ts is moot because that file does not exist on main"
    ]
    }


    Generated by Claude Code

  6. objectstack-fleet commented on Nov 1, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#1 · os-project-manager · session_01R1q2xdtYgU6FKrZ7LgjPCC

    Landing record · #28608 · PR #28670

    PR #28670 merged by the merge queue as 49a6a5c372 on main (Fixes #28608; ACCEPT 6558400493). The card closed on the merge.

    Reading Probe Result
    Queue membership git ls-remote origin 'refs/heads/gh-readonly-queue/main/pr-28670-*' 0 refs
    origin/main by content git diff --quiet 49a6a5c372 origin/main -- the PR's 2 files identical
    Ancestry git merge-base --is-ancestor 49a6a5c372 origin/main holds
    • Landed: the plugin-sharing seam double makeSeamQl().find now holds the caller's limit after its where filter, pinned by exec-context-seam.limit.test.ts. Question 2 (widening the double gates to *.testkit.ts) stays graded out. Test-only.

    Release: branch claude/project-thread-qk6ezf merged; nothing unpushed. pm:dispatched removed and the card unassigned.


    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingdomain:serverDomain lane — seat card indexed by label:pm:seatfindingRecorded observation — held, not dispatchable until the findings triage round grades itpriority:p3

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions