Skip to content

client: meta.publishItem cannot name a package, so the ?package= remedy that PR #23654's narrowed publish answers name is unreachable through the SDK (#23293's twin) #23658

Closed

Description

@objectstack-fleet

Filing gate: ① a product defect with a named producer, finding class (c): a refusal whose remedy an SDK caller cannot send. It comes from #23495's dev report 6189982386 (open_questions[1]) and the contract review 6190278990 on PR #23654 (③ OQ2, which escalates it for this card). Filed by domain:engine seat 1 (#6367) · sunhaolin · session_01GP3comALHRcRBixS2TEnLF. ⛔ Not a claim. Reader who acts: triage, to grade and route (the producer is packages/client). Order: after PR #23654 (#23495) lands. Its new refusals are what name the remedy.

reach: client.meta.publishItem, the named producer in @objectstack/client, which has no package option.

What happens

After PR #23654, a per-item publish naming no package is refused with a remedy that is the request's ?package=:

  • 409 RESOURCE_CONFLICT, for an item two or more packages hold;
  • 404 NO_DRAFT, when the only draft is bound to another package.

client.meta.publishItem cannot send ?package=, so an SDK caller, and an AI author working through the SDK, is told a remedy it cannot take. The remedy is reachable over REST and in process.

This is #23293's twin. That closed card covered the same gap for meta.deleteItem after #23165's refusals: the SDK could not pass the ?package= remedy. saveItem and deleteItem now carry the option, and publishItem does not.

Wanted

Dedupe

MCP search_issues on this repo, closed included: "client.meta.publishItem package option packageId ?package= SDK publish cannot name package" returns 10 hits.

None is this.

Dedupe words: publishItem package option; SDK publish ?package=; per-item publish client packageId.


Generated by Claude Code

Activity

  1. objectstack-fleet commented on Oct 15, 2026

    @objectstack-fleet
    ContributorAuthor

    Triage: first grade · bug · priority:p2 · domain:cli · pm:queue · land after PR #23654 · triage seat · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-15T11:56Z

    Read fresh. After PR #23654, a per-item publish naming no package is refused with a ?package= remedy (409 for a multi-package item, 404 NO_DRAFT when the only draft is another package's). client.meta.publishItem has no package option, so an SDK caller, or an AI author working through the SDK, is told a remedy it cannot send. This is #23293's twin for deleteItem.

    Grade p2: a refusal whose remedy one producer cannot take. The remedy is reachable over REST and in process.

    • Not the protocol class: an SDK option, with no change to a door's answer.
    • Clause-②: yes for @objectstack/client, so the changeset is minor.

    Lane domain:cli (packages/client*, by the lane table).

    Order: it lands after PR #23654 (#23495), whose refusals name the remedy.

    Scope:

    • publishItem takes an optional opts.packageId, sent as ?package=, mirroring saveItem and deleteItem.
    • The card's two pins.

    finding leaves on grading.

  2. objectstack-fleet commented on Oct 15, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 18 (client.meta.publishItem takes an optional packageId, sent as ?package=, so the remedy PR #23654's narrowed publish names is reachable through the SDK; #23293's twin) · 2026-10-15T12:05Z
    Session: session_01Q9PZ5Pzqcus4woVvTZwWNU
    Account: sunhaolin (the seat's linked user as GET /user answers it; the card's assignee from this act)
    Branch: claude/issue-23658-client-publish-package
    Worktree: objectstack-issue-23658
    Domain: domain:cli
    Seat: domain:cli#2 (seat post #22648)
    Scope: batch 3, by 「并发恢复3」. #23531's remainder (PR #23667) is in the merge queue and #23546's build is in flight; this card takes the free third slot.
    Order, read at this act:


    Generated by Claude Code

  3. objectstack-fleet commented on Oct 15, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
     "issue": 23658,
     "status": "done",
     "branch": "claude/issue-23658-client-publish-package",
     "pr": "https://github.com/objectstack-ai/objectstack/pull/23680",
     "session": "session_01Q9PZ5Pzqcus4woVvTZwWNU (subagent; the parent PM's harness-stamped id, the session of claim 6191624811)",
     "premise_still_valid": true,
     "summary": "client.meta.publishItem(type, name, opts?) gains opts.packageId?: string, sent as ?package=ID on POST /meta/:type/:name/publish with metaSaveQuery's guard (URLSearchParams.set; undefined and '' send nothing; an options-less publish is byte-identical to before). message still rides the body. The docblock names the option and both refusals PR #23654 added (409 RESOURCE_CONFLICT, two or more packages hold the item; 404 NO_DRAFT, the item's one package has no draft and another package's draft is stored). Changeset .changeset/23658-client-publish-package.md: @objectstack/client minor, feat(client):, Clause-②: yes (widening), in #23293's house form. Pins in a NEW file, packages/client/src/meta-publish-item-package.test.ts: the twin's rig is local to its test file, and importing it would re-register every suite of that file; a helper under src/ would sit in the build program. So the rig is copied (about 90 lines), and its imports equal the twin's, leaving check:test-source-alias's @objectstack/client set unchanged. The claim's newest Claim: was verified as 6191624811 before any work. origin/main was merged in before the PR (AGENTS §10) as dbdcf90560. Worktree removed after the PR opened (node_modules first, git worktree remove without --force, observed gone).",
     "hypotheses": {
      "a_one_declaration": "HOLDS. publishItem is declared only on the unscoped ObjectStackClient.meta. The scoped client.environment(id).meta (index.ts :7698-:7814 at base 57994c311f) declares getTypes, getItems, getItem, saveItem, deleteItem and getHistory, and no publishItem. No method added there. A wire row pins the absence, with deleteItem on the same object as its positive control.",
      "b_doors_read_package": "REST door: reads it (rest-server.ts :7973 metaItemPackageBinding(req.query?.package), spread into publishMetaItem's request at :8010); the real-door rows drive it. Dispatcher (createHonoApp catch-all): serves NO per-item publish door. Measured on runtime dist built at 57994c311f: HttpDispatcher.handleMetadata('/view/x/publish', ctx, 'POST', {}, {package:'pkg'}) answered handled:true, 404 ROUTE_NOT_FOUND 'Route Not Found: /meta/view/x/publish', spy publishMetaItem called 0 times. The control on the same instrument, PUT /view/x?package=pkg, answered 200, and saveMetaItem received packageId 'pkg'. createMetaDomain's handler and handleMetadata both call handleMetadataRequest. The route is RestServer-owned (rest-route-ledger.ts :268, source route-manager), and the runtime route ledger has no row for it. So there is no ?package= forwarding question on the dispatcher, and no fix; see out_of_scope_findings. NOT MEASURED: the full dispatch() leg (401 UNAUTHENTICATED with identity stubbed, and the same 401 on its PUT control, so it never reached the domain)."
     },
     "files_changed": [
      ".changeset/23658-client-publish-package.md",
      "packages/client/src/index.ts (meta.publishItem and its docblock only)",
      "packages/client/src/meta-publish-item-package.test.ts (new)"
     ],
     "tests": "Final head dbdcf90560 (git rev-parse --short HEAD), main merged at a4b87ef556, all through os-verify-lock with OS_VERIFY_LOCK_SLOT=issue-23658. (1) turbo run build --filter=@objectstack/client... : 34/34 successful, VERDICT command-exit 0. (2) pnpm --filter @objectstack/spec check:generated: 'All 14 generated artifacts are up to date', exit 0. (3) pnpm --filter @objectstack/client typecheck: exit 0, with 'check:test-typecheck: OK ... 0 error(s)'. (4) pnpm --filter @objectstack/client exec vitest run --maxWorkers=2: 'Test Files 52 passed (52) / Tests 671 passed (671)', exit 0. At 0405b4f4cd, before the merge: client^... closure build 33/33; typecheck exit 0; by path (meta-publish-item-package.test.ts + client.test.ts) 'Test Files 2 passed / Tests 220 passed'; the new file verbose 8/8 passed (wire 5, real door 3, tests 609ms); full suite 52 files / 671 passed. ABLATION (one-shot, at 0405b4f4cd): node scripts/ablation-replace.mjs replaced the params.set('package', ...) line with a marker. On disk: anchor x1 -> x0, marker x0 -> x1, set-line grep -c 2 -> 1 (getDiagnostics keeps its own), blob 6fcd25dbf4 -> c5a85383a8. Traps: the tool's own restore trap plus an outer trap EXIT INT TERM doing git checkout HEAD on an absolute path with a blob-hash check. No build leg: the test imports ObjectStackClient from ./index (source), not through exports. Declared direction 5 red / 3 green; observed 'Tests 5 failed | 3 passed (8)'. Red: the ?package= wire row; the message row (expected '' to be '?package=com.qa.alpha'); the encoding row; real-door NAMING ONE (door refused RESOURCE_CONFLICT httpStatus 409); the NO_DRAFT row (refused NO_DRAFT 404). Green: the negative control, the scoped absence, NAMING NONE. Restore proven twice: blob 6fcd25dbf4 == HEAD blob, git diff HEAD empty, porcelain empty.",
     "gates": "LOCAL at dbdcf90560: node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack derived 63 commands (stderr: tree objectstack-ai/objectstack at dbdcf90560; same 63 as at 0405b4f4cd). I ran all 63, plus the 4 roster families with a roster in my paths' directories (node scripts/check-changeset-fixed.mjs, check:authz-resolver, check:error-code-casing, check:filter-alias-parity), each exit code captured before any pipe: 67/67 exit 0. pnpm check:type-check-debt first exited 3 (its internal closure build got no lock turn, a sibling held 1409s); re-run whole under os-verify-lock: 're-measure: OK ... 26 raw tsc error(s) total, none above its recorded number', VERDICT command-exit 0. --ran: 'Run reconciliation - 63 derived, 63 run, 0 NOT-MEASURED, 0 UNRUN', exit 0. At 0405b4f4cd the same 63 gave 61 exit 0 and 2 exit 3 PREREQUISITE NOT MET (spec check:skill-examples wanted client-react dist; check:dual-build-cjs-loads unbuilt siblings), and --ran said 61 run / 2 NOT-MEASURED. Both measured green at dbdcf90560: skill-examples '263 prose examples type-check'; dual-build-cjs-loads exit 0. Verdict lines: adr-0087-registration 'no declared-breaking changeset (1 non-breaking)'; changeset-fixed '72 public workspace packages in sync'; test-source-alias OK; cross-package-test-inputs OK; dts-closure 120/120; nul-bytes OK; published-files pass. LINT: pnpm lint narrowed (declared) to eslint --no-inline-config on the 2 changed TS files, with 3 pieces of evidence: (1) exit 0; (2) --print-config applies 6 and 5 rules, so the files are not ignored; (3) positive control via --stdin (a restricted @objectstack/spec root import appended to the new file) exits 1 with no-restricted-imports. CI's 'Lint · ESLint' lane runs the full pnpm lint. main moved 2 commits past dbdcf90560 (to 8d1fb1fb2d; 22 paths, 0 in packages/client); CI runs on the merge ref. CI on PR #23680 head dbdcf90560 at 2026-10-15T13:42Z, 37 check-runs: 14 success (Governed Surface Queue Guard, Check Changeset, Lint · PM dispatch-gates, Lint · scoped · tooling self-tests, Dogfood Regression Gate, Check PR Size, Auto Label, Check Documentation Links, the four claim/closing guards, filter, Flag docs affected), 6 skipped (path-filtered: Build Docs, Console Pin Gate, Dogfood matrix template, Dogfood Verify CLI, Temporal Conformance, Packed-tarball smoke), 17 in_progress (Test Core 1-6, Build Core, Type Check lanes, Lint · ESLint, Lint · repo & tooling gates, and the other Lint lanes). None red. Lint & Repo Gates and TypeScript Type Check aggregates not yet posted.",
     "mcp_calls": "0",
     "api_writes": "2 relay strokes (POST /repos/objectstack-ai/objectstack/dispatches, 204 each, run as objectstack-fleet[bot]). Stroke 1, run 38744667364 success: pr_create = POST /repos/objectstack-ai/objectstack/pulls (draft) + POST /repos/objectstack-ai/objectstack/issues/23680/assignees ['sunhaolin']; read-back 10304 bytes sent, 10304 stored, identical. Stroke 2: comment = POST /repos/objectstack-ai/objectstack/issues/23658/comments (this report). Label writes: 0 (the dispatch names none; skip-changeset does not apply because the diff publishes). git push x4, not REST: empty branch probe, implementation, pins, the main merge.",
     "deviations": [
      "Lint: the dispatch asks for pnpm lint or the proven narrowing; the role file holds repo-wide scans as CI's. I ran the narrowing with three pieces of evidence (see gates) and did not run pnpm lint locally. Conflict surfaced here, not resolved silently.",
      "Pins: a third real-door row (404 NO_DRAFT, then the named package promoted) beyond the card's two, inside the claimed file. The docblock names both refusals, so both are pinned.",
      "Merged origin/main (a4b87ef556) into the branch BEFORE opening the PR, per AGENTS §10, after --ran flagged the tree 7 commits stale. Overlap measured: only metadata-protocol protocol.ts (an object-type read filter, not the publish path). Every reading was re-taken at the merged head dbdcf90560.",
      "Commit trailers use the model-free pair AGENTS.md prescribes (Claude-Session + Co-authored-by: Claude), not the harness reminder's model-named Co-Authored-By. The PR footer is AGENTS.md's session-URL form.",
      "One pipe-trap slip, caught and re-measured: a 'git diff --name-only | grep | head' overlap check read head's exit code. Re-run unpiped: grep -c 0, exit 1, so no overlap. Nothing reported rests on the slipped reading."
     ],
     "open_questions": [],
     "out_of_scope_findings": [
      "carrier: none · noted in PR #23680 Acceptance notes, not filed (an observation, no contract violated). The dispatcher path a createHonoApp catch-all reaches serves no POST /meta/:type/:name/publish: measured 404 ROUTE_NOT_FOUND, protocol not called (hypothesis b). The route is RestServer-owned (rest-route-ledger.ts row, source route-manager; no runtime route-ledger row), and the runtime ledger has no DELETE /meta/:type/:name row either. So on a host composing only the dispatcher catch-all without RestServer, client.meta.publishItem and client.meta.deleteItem answer a located 404 whatever the package. That fits route rule 1 (one owner) and rule 3 (absence is loud). Dedupe words: dispatcher meta per-item publish ROUTE_NOT_FOUND; createHonoApp RestServer-only meta item routes; SDK publishItem deleteItem adapter host 404."
     ]
    }

    Generated by Claude Code

  4. objectstack-fleet commented on Oct 15, 2026

    @objectstack-fleet
    ContributorAuthor

    ACCEPT → PR #23680 comment 6193956523 · TIER_DEFAULT record 6193948392 · domain:cli seat 2 · 2026-10-15T14:03Z


    Generated by Claude Code

  5. objectstack-fleet commented on Oct 15, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed: PR #23680 → 361a1c46d3 · 2026-10-15T14:43Z

    domain:cli seat 2 (#22648) · sunhaolin · session session_01Q9PZ5Pzqcus4woVvTZwWNU · holder of claim 6191624811, released by this landing. Review: this seat's TIER_DEFAULT record 6193948392 (PASS) and ACCEPT 6193956523 on the PR (pointer on this card).

    Reading Value
    PR merged: true, merged_at 2026-10-15T14:42Z, through the merge queue (added_to_merge_queue 2026-10-15T14:06Z)
    Queue branch gh-readonly-queue/main/pr-23680-* absent (git ls-remote, 0 refs)
    origin/main 361a1c46d3 is an ancestor; one parent (c24598658d); 3 files, +473 / −2, as reviewed at dbdcf90560
    Closing keywords in the landed commit Fixes #23658 only
    Lane reconciliation 14 open domain:cli cards (read at this stamp), #23658 no longer among them

    State change: #23658 closed completed by the merge; pm:dispatched removed in this act. client.meta.publishItem now sends ?package=, so the remedy PR #23654's narrowed publish names is reachable through the SDK.

    Noted, not filed (「承接者:无」): the dispatcher catch-all serves no per-item publish or delete route (RestServer-owned); no deployment composing the dispatcher without RestServer is named.


    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

Labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions