Skip to content

cli: os meta delete prints "✓ Metadata deleted" when the reset door removed nothing (reset: false), including a --package that holds no row of the item #23479

Closed

Description

@objectstack-fleet

Filing gate ①, finding class (a): a reproducible defect with misleading user-visible text, measured at a public door. Filed by domain:spec seat 1 (#6017) · huangyiirene · session session_01YRp5z4kK6vgYkrdH97ztsy, from #23350's dev report (PR #23475, out-of-scope finding 1). ⛔ Not a claim. Grade and lane are triage's.

reach: the public CLI door os meta delete, human output (the default --format). Measured by the #23350 dev with a one-off probe through the real oclif command against the real reset door, on PR #23475's head 7ec2fb6c7. The probe was not kept.

Reader who acts: triage, to grade and route. Then the owning seat. The landing point is packages/cli/src/commands/meta/delete.ts, in run()'s human-output branch.

What happens

The human branch prints its success sentence without reading result.reset. An operator, or a script reading the human line, is told an item was reset when the door reset nothing.

What done looks like

  • When the door answers reset: false, the human output says so. For example: nothing to delete for view/nothing_here (and, with --package P, that P holds no row of it). The exit code follows whatever the command already declares for a no-op, measured and stated.
  • A pin on each branch: reset: true prints the success line, and reset: false prints the no-op line. Each has a negative control.

Dedupe

MCP search_issues on objectstack-ai/objectstack, closed included:

Dedupe words: os meta delete human output reset false; Metadata deleted when nothing removed; meta delete deleted false sentence.


Generated by Claude Code

Activity

  1. objectstack-fleet commented on Oct 14, 2026

    @objectstack-fleet
    ContributorAuthor

    Triage: first grade · bug · priority:p2 · domain:cli · area:devpath · pm:queue · triage seat · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-14T12:55Z

    Read fresh.

    • priority:p2: the human face of os meta delete reports success ("✓ Metadata deleted") when the reset door removed nothing (reset: false), including for a --package that holds no row. The JSON face is right. An operator, or a script reading the line, is told something false.
    • Lane domain:cli (packages/cli/src/commands/meta/delete.ts, the human branch). Clause ②: no. It changes the text and, if measured, the no-op exit code; not what the door accepts.
    • Scope as filed: the no-op line on reset: false, the exit code as the command already declares for a no-op, and pins on both branches with negative controls.
    • finding leaves on grading.
  2. objectstack-fleet commented on Oct 14, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 10 (#23479: os meta delete's human output says nothing was deleted when the reset door answers reset: false, including for a --package that holds no row; the exit code follows what the command declares for a no-op) · 2026-10-14T23:27Z
    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-23479-meta-delete-noop-line
    Worktree: objectstack-issue-23479
    Domain: domain:cli
    Seat: domain:cli#2 (seat post #22648)
    Scope: the maintainer's 「并发加到3」 (about 2026-10-14T23:23Z). This is the third of the three in flight. It is the lane's oldest p2 bug after the target:v18 cards.
    File surface (read on origin/main 0b9391b827; stop on a breach and explain it in the report):

    • packages/cli/src/commands/meta/delete.ts, ONLY run()'s output branch (about :200-:230). Today the human face prints "Metadata deleted: TYPE/NAME" without reading result.reset. The JSON and YAML faces already carry deleted: result.reset.
    • One pin file beside the command's suites (packages/cli/test/meta-delete*.test.ts or the nearest sibling), and one .changeset/23479-*.md (@objectstack/cli patch).
    • ⛔ Not the reset door (packages/metadata-protocol, packages/rest), not packages/client, not packages/spec.

    Container & model: S, judged (one output branch, two pins), mode:subagent, model: default tier. Ceiling: Clause-②: no (operator text; triage 6168846133). If the measurement changes the no-op exit code, the dev states it, and this seat re-grades. No contract face, so CI plus this seat's read.
    Clause-②: no
    Responsibility: os meta delete's human output in packages/cli (this lane) | the reset door's DeleteMetaItemResponse.reset, read, not changed | every operator or script reading os meta delete's human line
    Thread-read: 6168846133
    Serial constraints cleared:


    Generated by Claude Code

  3. objectstack-fleet commented on Oct 15, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
     "issue": 23479,
     "status": "done",
     "branch": "claude/issue-23479-meta-delete-noop-line",
     "pr": "https://github.com/objectstack-ai/objectstack/pull/23557",
     "session": "session_01Q9PZ5Pzqcus4woVvTZwWNU (subagent; the parent PM's harness-stamped id, the session of claim 6180747022)",
     "premise_still_valid": true,
     "summary": "Verified the premise on origin/main 086fa4640f: run()'s human branch in packages/cli/src/commands/meta/delete.ts printed 'Metadata deleted' (or 'Pending draft discarded' under --draft) without reading result.reset, while the JSON and YAML outputs print deleted: result.reset. The human branch now reads result.reset === false (the sibling os data delete's reading) and prints a warning line built from the flags it sent. The four lines are: 'Nothing deleted: TYPE/NAME — the server found nothing to delete'; with --package P, 'Nothing deleted: package 'P' holds no row of TYPE/NAME'; with --draft, 'Nothing discarded: TYPE/NAME has no pending draft'; and with --draft --package P, 'Nothing discarded: package 'P' holds no pending draft of TYPE/NAME'. Each sentence mirrors the claim the door's own reset:false receipt makes for that address and names no cause the CLI did not read. The reset:true success line is byte-identical. Exit code (hypothesis b), measured: the command already declares a no-op as exit 0. Its JSON and YAML outputs publish success:true beside deleted:false, delete-reset-carriers.test.ts already pins two real-door no-ops at exit 0, the docblock and cli.mdx declare nothing else (cli.mdx has no os meta delete entry), and the real-door probe exits 0 on all five no-ops. So the exit code is UNCHANGED at 0 on both values and all three formats, and failures still exit 1. The landing stayed on the claimed file surface: delete.ts run()'s output branch plus a module-private noOpLine helper beside it, one pin file and one changeset. Hypothesis (a) held, including the --draft variant, which needed its own no-op wording. Hypothesis (c) held: with --package P and reset:false, the door's probe at (state, P) found no row, on both door paths.",
     "tests": "Pin file packages/cli/src/commands/meta/delete-noop-line.test.ts (unit tier, 7 cases): real oclif command, real ObjectStackClient with a canned door receipt, 4 argv variants (none, --package, --draft, --draft --package). POSITIVE CONTROL: the receipts pass the real SDK verbatim. reset:true gives the whole output equal to the success line, with a negative control (no 'Nothing deleted/discarded'). reset:false gives the whole output equal to the no-op line, with a negative control (no 'Metadata deleted', no 'Pending draft discarded', no success glyph). --package names P verbatim, with a negative control (the package-less line names no package). JSON, YAML and human outputs agree, and humanClaim refuses an output with neither sentence or both. Exit 0 on both values x 3 formats x 4 variants, with a control: a 500 still exits 1. Targeted run: 'vitest run --project unit --maxWorkers=2 delete-noop-line.test.ts delete-json-error-code.test.ts' -> Test Files 2 passed, Tests 13 passed (VERDICT command-exit 0). ABLATION (fix committed first at c52520177f): node scripts/ablation-replace.mjs mutated 'if (result.reset === false) {' to 'if (false) {' (anchor x1->x0, replacement x0->x1, blob 291bceebf307->16421ba34632). WRAP run of the pin file: 'Tests 3 failed | 4 passed (7)'. Red were the reset:false case (received '  ✓ Metadata deleted: view/nothing_here'), the --package case and the arms-agree case. Green were the positive control, reset:true, the exit-code pin and the transport control. The direction is red, as predicted. Restore proven: 'blob == HEAD (291bceebf307) and git diff HEAD is empty'. The subject is imported relatively from src, so no dist rebuild was needed. REAL-DOOR PROBE (one-off, not kept; harness of delete-reset-carriers.test.ts; real RestServer, protocol and SQLite) on c52520177f: nothing_here -> '  ⚠ Nothing deleted: view/nothing_here — the server found nothing to delete' exit 0, JSON deleted:false; --package com.qa.gamma (alpha and beta hold rows) -> '  ⚠ Nothing deleted: package 'com.qa.gamma' holds no row of view/probe_v' exit 0, JSON deleted:false; --package with nothing stored -> package line, exit 0; --draft with no draft -> '  ⚠ Nothing discarded: view/probe_d has no pending draft' exit 0; --draft --package -> package draft line, exit 0; control (a real delete) -> '  ✓ Metadata deleted: view/probe_ok' exit 0. Same run: delete-reset-carriers.test.ts (integration) green, 2 files, 34 tests. On final head 41060487d3: 'pnpm --filter @objectstack/cli typecheck' exit 0, and the new file is in that tsc program (tsc --listFilesOnly lists it). 'pnpm --filter @objectstack/cli exec vitest run --project unit --maxWorkers=2': 288/290 files and 4295 tests passed, 29 skipped. The 2 failed files (test/published-subpath-console.pin.test.ts, test/published-subpath-hook-body.pin.test.ts) refused at load: 'packages/cli is not built (./dist/index.js is absent)', a prerequisite and not a finding. Re-run after the full build: 2 files, 29 tests passed, exit 0. The integration tier is declared to CI except the carriers file run above.",
     "gates": "Local, on head 41060487d3, exit codes captured before any pipe. 'node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack' derived 64 commands, and all 64 were run. First pass: 60 exit 0, and 4 exit 3 (PREREQUISITE NOT MET, unbuilt dist): check:dual-build-cjs-loads, check:i18n, check:i18n-coverage, check:i18n-walk-parity. After a full 'pnpm turbo run build --filter=!@objectstack/docs --concurrency=2' (VERDICT command-exit 0, 75/75 tasks), those 4 plus check:dts-closure, check:lean-entry-closure, check:published-files and check:sourcemap-no-sources-content were re-run: all exit 0. Verdict lines: 'check-i18n-bundles: OK (10 package(s)...)', 'check-i18n-coverage: OK (14 config(s)... none new)', 'check-i18n-walk-parity: 11 declared group(s), 9 walked, 2 exempted', 'check-dts-closure: 75 built package(s) swept - 176/176...', 'check-sourcemap-no-sources-content: 71 built package(s) swept - 568 map(s), none embed source text'. '--ran' reconciliation: '64 derived, 64 run, 0 NOT-MEASURED, 0 UNRUN' (a derived zero, every line carrying its exit code). 'pnpm lint' (whole-repo eslint --no-inline-config): exit 0, no findings. check:dev-prereqs and check:skill-frame-freshness were not run: the diff touches neither the packages/spec build nor the frame files. CI on PR #23557, read once at head 41060487d3 (23 check-runs): 'No other open PR may claim the same issue' success; 'Packed-tarball smoke (opt-in)' skipped; in_progress: Check Changeset, Check Documentation Links, Check PR Size, Flag docs affected by code changes, Governed Surface Queue Guard, Lint · CI, release & engine gates, Lint · ESLint, Lint · PM dispatch-gates, Lint · docs & code guards, Lint · repo & tooling gates, Lint · scoped · query-options erasure, Lint · scoped · slot lookup & corpus, Lint · scoped · tooling self-tests, No other open PR may claim the same single-writer path, Part-of PR must not also close its card, The card this PR closes must claim this branch, Type Check · consumer gates, Type Check · debt ledger, Type Check · source gates, Type Check · workspace, filter. Not yet listed at the read: Test Core, Build Core. CI convergence is the PM's.",
     "mcp_calls": "0",
     "api_writes": "2 relay strokes, each one seat-side POST /repos/objectstack-ai/objectstack/dispatches (fleet-write, as objectstack-fleet[bot]). Stroke 1, run 38658306695: pr_create -> POST /repos/objectstack-ai/objectstack/pulls (draft) + POST /repos/objectstack-ai/objectstack/issues/23557/assignees [sunhaolin]; read-back: 10910 bytes sent, 10910 stored, identical. Stroke 2: comment -> POST /repos/objectstack-ai/objectstack/issues/23479/comments (this os-dev-report). label-write: 0 (the dispatch named none, and skip-changeset does not apply because the diff publishes a patch). git push (not REST): 3 (the empty-branch probe, the fix commit, the changeset commit).",
     "open_questions": [],
     "out_of_scope_findings": [
      "carrier: none (承接者:无) · noted, not filed · The door's no-op receipt message (for example 'No row of view/x is bound to package 'P', so nothing was deleted: package 'com.qa.alpha' still holds a row') is surfaced on no os meta delete output. JSON and YAML print { success, type, name, deleted } only. Surfacing it is a new output key or line, which is outside this card. In PR Acceptance notes. Dedupe words: os meta delete door message not surfaced; meta delete receipt message; deleted false reason.",
      "carrier: none (承接者:无) · noted, not filed (read-only inference, not exercised; no reach) · The reset door's legacy raw-engine path (packages/metadata-protocol/src/protocol.ts, deleteMetaItem, the control-plane code-only branch) matches the row by type, name and organization_id null and reads neither request.state nor request.packageId. A --draft or --package reset there would remove whatever row it finds. Dormant: unreachable from an environment kernel, and draft or packaged rows of the code-only types are not writable. In PR Acceptance notes. Dedupe words: legacy raw-engine delete ignores packageId; deleteMetaItem legacy path state draft; control-plane code-only delete package."
     ],
     "deviations": [
      "Base: the worktree was cut from origin/main 086fa4640f, not the dispatch's 0b9391b827. One commit (#23550) landed between them, and it adds only packages/cli/test/serve-organization-record-page.e2e.test.ts, with no overlap. At PR time origin/main was b57228913a (+1 spec test commit, no overlap), so there was no merge.",
      "Attribution: the harness reminder asked for a model-named Co-Authored-By trailer and a '🤖 Generated with' PR footer. Per AGENTS.md (it outranks the reminder), commits carry the model-free pair 'Claude-Session: https://claude.ai/code/session_01Q9PZ5Pzqcus4woVvTZwWNU' and 'Co-authored-by: Claude', and the PR body ends with the session-URL footer. The pre-push hook confirmed it: 'check:commit-card-trailers: ... no model identifier in the trailer pair'.",
      "pnpm lint: the dispatch says this lane always adds it, and the role file says repo-wide scans are CI-owned and never owed. I ran the full 'pnpm lint' anyway (exit 0), so both are satisfied. No narrowing was declared.",
      "Build scope: beyond the ① dependency closure ('turbo run build --filter=@objectstack/cli^...'), I ran a full workspace build (minus docs). Four derived gates and two CLI unit pins refused on unbuilt dist (packages/cli itself plus 9 packages outside the closure). Those first-pass exit-3s and load refusals are recorded above as prerequisites, not as measurements.",
      "The ablation and the real-door probe ran on c52520177f (the fix commit), before the changeset-only commit 41060487d3. The code under test is byte-identical at both (delete.ts blob 291bceebf307)."
     ],
     "files_changed": [
      "packages/cli/src/commands/meta/delete.ts",
      "packages/cli/src/commands/meta/delete-noop-line.test.ts",
      ".changeset/23479-meta-delete-noop-line.md"
     ],
     "cleanup": "Worktree /home/user/objectstack-issue-23479 removed (node_modules first, then git worktree remove without --force, exit 0) after confirming git status clean and origin at 41060487d3. The one-off probe file was removed by its own trap (confirmed absent). No background process of this run is alive: the build (18095, 24498), unit (27023) and gate-runner (26510, 5240) jobs all exited."
    }

    Generated by Claude Code

  4. objectstack-fleet commented on Oct 15, 2026

    @objectstack-fleet
    ContributorAuthor

    ACCEPT → PR #23557 comment 6181337126 · 2026-10-15T00:13Z


    Generated by Claude Code

  5. objectstack-fleet commented on Oct 15, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed: PR #23557 → 252775d1d3 · 2026-10-15T00:52Z

    domain:cli seat 2 (#22648) · sunhaolin · session session_01Q9PZ5Pzqcus4woVvTZwWNU · holder of claim 6180747022, released by this landing. Review: seat record 6181337126 on the PR (pointer on this card). No contract review was owed.

    Reading Value
    PR merged: true, merged_at 2026-10-15T00:51Z, through the merge queue (added_to_merge_queue 2026-10-15T00:30Z)
    Queue branch gh-readonly-queue/main/pr-23557-* absent (git ls-remote, 0 refs)
    origin/main 252775d1d3 is an ancestor; one parent (7ffc57846a); 3 files, +390 / −10, as reviewed
    Closing keywords in the landed commit Fixes #23479 only
    Lane reconciliation 18 open domain:cli cards (read at this stamp), #23479 no longer among them

    State change: #23479 closed completed by the merge; pm:dispatched removed in this act.


    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

area:devpathThe road — create, dev, verify, publish/install, connect an agent, iteratebugSomething isn't workingdomain:clipriority:p2Medium: important, M3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions