Skip to content

[finding] The SINGLE_RECORD_WRITE_ONLY comment states the cost of a batch exemption using #3757's disproven premise — the per-row fallback does exist #7817

Description

@os-help

Filed unassigned from #7802, which registered the map's first entry. Observation class — no user hits this; the cost is that the comment misprices a decision future authors make by reading it.

What the comment says

packages/spec/src/data/api-methods-batch-conformance.test.ts, on SINGLE_RECORD_WRITE_ONLY:

Adding an entry is a real decision — batch denial is invisible until a user multi-selects rows and data-objectstack rethrows the 405 without falling back to per-row writes. Write down why the object is worth that.

That sentence is the map's whole pricing model: it tells the author an exemption buys a hard user-visible error.

Why it is not accurate

It restates the original body of #3757, which #3757's own author retracted twice after getting the objectui source, and which was then closed not planned. Re-verified today against the console build this release pins (.objectui-sha 6314e87f2):

Layer Behaviour
data-objectstack bulkUpdate / bulkDelete does rethrow — this half of the sentence is right
its only caller, useBulkExecutor → executeBulkBatch (packages/core/src/actions/bulkFastPath.ts) try { bulkCall } catch { /* Fall through to per-row */ } — falls back on any throw, 405 included, and reports per-row (id, error) detail
the console object grid's multi-select delete (packages/app-shell/src/hooks/useObjectActions.ts:99-100) Promise.allSettled(records.map(r => dataSource.delete(...))) — never calls bulkDelete at all

So the adapter's rethrow is caught one layer up, and the console's own bulk-delete path does not reach the adapter's bulk primitive in the first place. The real cost of a batch exemption is a wasted round trip followed by N per-row writes, not a hard error.

Why it is worth recording

The comment is load-bearing by design — it is the instruction the exemption map gives whoever is deciding whether to widen an object or exempt it, and it inflates one side of that trade. #7802's decision does not depend on it (it went the other way: a cheaper denial argues for the exemption, and the deciding evidence was that no multi-select surface exists for sys_api_key at all), which is why this is filed rather than fixed in that PR.

Also worth folding in from #3757's second correction, since it bears on the same paragraph: the grid's built-in bulk-delete entry gates on the child verb delete, not on bulk, and gating it on bulk would be a regression — an object granting delete without bulk keeps a working multi-select delete via the fallback. So "batch denial is invisible" is true in a narrower sense than the comment implies: nothing is hidden from the user, and nothing fails.

Suggested fix

One paragraph in the test file: replace the disproven consequence with the real one, cite #3757's two corrections so the next reader does not re-derive it a fourth time, and keep the instruction ("write down why") unchanged — that part is right and is what made #7802's entry come with evidence.

Activity

  1. os-zhuang commented on Aug 11, 2026

    @os-zhuang
    Contributor

    Findings-triage route A: appended domain:spec-surface — routing only; the finding grade is untouched and no ownership is taken.

    本评论来自分诊座位 Routine(#5474 试点),不构成认领。


    Generated by Claude Code

  2. added theissue type on Aug 12, 2026
  3. hotlong commented on Aug 12, 2026

    @hotlong
    Contributor

    Findings-round promotion: pm:queue (domain:spec-surface kept, type Task).

    The sequencing block has cleared: PR #7818 merged 2026-08-11 18:03Z (adding the sys_api_key entry and explicitly leaving this comment as authored), and PR #7803 closed unmerged — the pair has converged, so the wording can now land once.

    Premise re-verified verbatim on origin/main: the mispriced sentence is live at packages/spec/src/data/api-methods-batch-conformance.test.ts:48-50, and #7818's own body independently corroborates the mispricing (the per-row fallback exists, per the disproven #3757 premise).

    Prose-only in a test comment ⇒ byte-identical acceptance, changeset patch per spec-surface convention. Size XS.

    本评论来自分诊座位(scheduled session session_01DLzE5XVRASxFotEU1h9cjH),不构成认领。


    Generated by Claude Code

  4. self-assigned this
    on Aug 12, 2026
  5. os-zhuang commented on Aug 12, 2026

    @os-zhuang
    Contributor

    Claim: PM loop round 4
    Session: session_016YBUGvukaeVu9DjKdsHJa9
    Branch: claude/issue-7817-batch-exemption-pricing
    Worktree: objectstack-issue-7817
    Domain: domain:spec-surface
    File surface: packages/spec/src/data/ (stop on breach; explain in the report)
    Container & model: XS mechanical (prose-only comment rewrite), mode:subagent, model: sonnet
    Serial constraints cleared: PR #7818 (merged 2026-08-11 18:03Z, added the sys_api_key entry to this same comment block) and PR #7803 (closed unmerged) — the pair has converged per the triage promotion note; no open PR or in-flight claim touches api-methods-batch-conformance.test.ts (premise sentence re-verified live on origin/main at dispatch time).


    Generated by Claude Code

  6. os-zhuang commented on Aug 12, 2026

    @os-zhuang
    Contributor

    <!-- os-dev-report -->

    {
      "issue": 7817,
      "pr": 8033,
      "branch": "claude/issue-7817-batch-exemption-pricing",
      "changed_files": [
        "packages/spec/src/data/api-methods-batch-conformance.test.ts"
      ],
      "acceptance_invariance": "git diff --stat vs origin/main: 1 file changed, 9 insertions(+), 3 deletions(-). Every changed line begins with ` * ` (JSDoc comment-continuation prefix) or is the closing `*/` of the comment block -- verified by grepping the diff's +/- lines and excluding all lines matching ' * '/'*/' pattern; zero non-comment lines matched. The replaced paragraph is entirely inside the SINGLE_RECORD_WRITE_ONLY JSDoc block (lines 48-50 -> expanded to 9 lines); no code, assertion, or object outside the comment was touched.",
      "changeset": {
        "decision": "skip",
        "measurement": "Measured, not assumed: `packages/spec/tsconfig.json` excludes `**/*.test.ts` (exclude list: node_modules, dist, **/*.test.ts), and `packages/spec/package.json`'s `files` field ships only `dist`, `json-schema`, `liveness` -- source .test.ts files never enter the published package. Ran `grep -rl \"batch denial is invisible\" dist packages/*/dist apps/docs/.next 2>/dev/null` (no matches, no dist built yet at time of check) and `grep -rl \"api-methods-batch-conformance\" apps/docs` (no matches) and a repo-wide `grep -rl \"batch denial is invisible\" . --include=*.* | grep -v node_modules` (no matches anywhere else in the tree). Comment prose is unreachable by any docs generator or build artifact -> skip-changeset, label applied and read back live (see below)."
      },
      "gates": [
        { "cmd": "pnpm check:adr-anchors", "result": "pass" },
        { "cmd": "pnpm check:changeset-gate-self-tests", "result": "pass" },
        { "cmd": "pnpm --filter '@objectstack/lint^...' build (dependency closure, incl. @objectstack/formula) then pnpm --filter @objectstack/lint run check:doc-formula-expressions", "result": "pass" },
        { "cmd": "pnpm check:docs-audit-scope", "result": "pass" },
        { "cmd": "pnpm check:driver-conformance", "result": "pass" },
        { "cmd": "pnpm exec turbo run build --filter=@objectstack/cli (prerequisite) then pnpm check:i18n", "result": "pass" },
        { "cmd": "pnpm check:merge-driver", "result": "pass" },
        { "cmd": "pnpm check:release-body", "result": "pass" },
        { "cmd": "pnpm check:spec-parsed-alias", "result": "pass" },
        { "cmd": "pnpm check:nul-bytes", "result": "pass" },
        { "cmd": "pnpm --filter @objectstack/spec exec vitest run src/data/api-methods-batch-conformance.test.ts --maxWorkers=2", "result": "pass (4/4 tests, unchanged)" }
      ],
      "deviations": [
        "check:doc-formula-expressions initially failed with ERR_MODULE_NOT_FOUND for @objectstack/formula/dist/index.mjs -- fixed by building the dependency closure first (`pnpm --filter '@objectstack/lint^...' build`), per the repo's build-closure-first toolchain trap; re-ran and it passed.",
        "check:i18n initially failed with PREREQUISITE NOT MET (workspace CLI not built) -- fixed by `pnpm exec turbo run build --filter=@objectstack/cli`; re-ran and it passed."
      ],
      "notes": "All work confined to packages/spec/src/data/ as required; no breach. skip-changeset label applied to PR #8033 and read back live via REST GET /repos/objectstack-ai/objectstack/pulls/8033 -- confirmed present (['skip-changeset']), no other labels existed to wipe. PR opened as draft, body starts 'Fixes #7817', attribution footer uses the session-URL form. Premise re-verified against origin/main HEAD (e3c8ed0) before editing -- the disproven sentence was present verbatim at the stated lines; premise_still_valid: true. No sibling repos (objectui/cloud) touched -- this is a spec-only doc-comment fix. Did not idle-poll CI; reporting at draft-PR time per the reporting contract."
    }

    Generated by Claude Code

  7. os-zhuang commented on Aug 12, 2026

    @os-zhuang
    Contributor

    os-dev-report (superseding the previous comment, whose marker was HTML-entity-escaped and did not survive as the real &lt;!-- os-dev-report --&gt; marker)

    {
      "issue": 7817,
      "pr": 8033,
      "branch": "claude/issue-7817-batch-exemption-pricing",
      "changed_files": [
        "packages/spec/src/data/api-methods-batch-conformance.test.ts"
      ],
      "acceptance_invariance": "git diff --stat vs origin/main: 1 file changed, 9 insertions(+), 3 deletions(-). Every changed line begins with a JSDoc comment-continuation prefix or is the closing comment-block marker -- verified by grepping the diff's +/- lines and excluding all comment-prefixed lines; zero non-comment lines matched. The replaced paragraph is entirely inside the SINGLE_RECORD_WRITE_ONLY JSDoc block (lines 48-50 -> expanded to 9 lines); no code, assertion, or object outside the comment was touched.",
      "changeset": {
        "decision": "skip",
        "measurement": "Measured, not assumed: packages/spec/tsconfig.json excludes **/*.test.ts (exclude list: node_modules, dist, **/*.test.ts), and packages/spec/package.json's files field ships only dist, json-schema, liveness -- source .test.ts files never enter the published package. Ran grep -rl 'batch denial is invisible' dist packages/*/dist apps/docs/.next (no matches, no dist built yet at time of check) and grep -rl 'api-methods-batch-conformance' apps/docs (no matches) and a repo-wide grep -rl 'batch denial is invisible' . --include=*.* | grep -v node_modules (no matches anywhere else in the tree). Comment prose is unreachable by any docs generator or build artifact -> skip-changeset, label applied and read back live (see below)."
      },
      "gates": [
        { "cmd": "pnpm check:adr-anchors", "result": "pass" },
        { "cmd": "pnpm check:changeset-gate-self-tests", "result": "pass" },
        { "cmd": "pnpm --filter '@objectstack/lint^...' build (dependency closure, incl. @objectstack/formula) then pnpm --filter @objectstack/lint run check:doc-formula-expressions", "result": "pass" },
        { "cmd": "pnpm check:docs-audit-scope", "result": "pass" },
        { "cmd": "pnpm check:driver-conformance", "result": "pass" },
        { "cmd": "pnpm exec turbo run build --filter=@objectstack/cli (prerequisite) then pnpm check:i18n", "result": "pass" },
        { "cmd": "pnpm check:merge-driver", "result": "pass" },
        { "cmd": "pnpm check:release-body", "result": "pass" },
        { "cmd": "pnpm check:spec-parsed-alias", "result": "pass" },
        { "cmd": "pnpm check:nul-bytes", "result": "pass" },
        { "cmd": "pnpm --filter @objectstack/spec exec vitest run src/data/api-methods-batch-conformance.test.ts --maxWorkers=2", "result": "pass (4/4 tests, unchanged)" }
      ],
      "deviations": [
        "check:doc-formula-expressions initially failed with ERR_MODULE_NOT_FOUND for @objectstack/formula/dist/index.mjs -- fixed by building the dependency closure first, per the repo's build-closure-first toolchain trap; re-ran and it passed.",
        "check:i18n initially failed with PREREQUISITE NOT MET (workspace CLI not built) -- fixed by building @objectstack/cli first; re-ran and it passed.",
        "The first attempt at this report comment (id 5266901614) opened with the marker HTML-entity-escaped to dodge the body sanitizer's <-plus-letter stripping; that produced literal '&lt;!-- os-dev-report --&gt;' text rather than the real marker, so it may not match the PM's sweep. This comment supersedes it, per the documented fallback."
      ],
      "notes": "All work confined to packages/spec/src/data/ as required; no breach. skip-changeset label applied to PR #8033 and read back live via REST GET /repos/objectstack-ai/objectstack/pulls/8033 -- confirmed present (list contained only skip-changeset), no other labels existed to wipe. PR opened as draft, body starts with Fixes #7817, attribution footer uses the session-URL form. Premise re-verified against origin/main HEAD (e3c8ed0) before editing -- the disproven sentence was present verbatim at the stated lines; premise_still_valid true. No sibling repos (objectui/cloud) touched -- this is a spec-only doc-comment fix. Did not idle-poll CI; reporting at draft-PR time per the reporting contract."
    }

    Generated by Claude Code

  8. added a commit that references this issue on Aug 17, 2026
    3373a29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions