Repository navigation
docs(skills): objectstack-api teaches the recycle bin a by-id delete keeps, not a hard delete - #30994
Conversation
…keeps The data-API table, the derived-verb note and the DELETE pitfall said a delete is hard and there is no recycle bin. A by-id delete of a business object now keeps its rows in sys_recycle_bin (30 days by default); multi deletes, platform rows and rows deleted before the bin existed are not in it, and no restore or purge door is exposed yet. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01J8VVAnsTJVz6nCb7n8NUJs
Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01J8VVAnsTJVz6nCb7n8NUJs
|
domain:skills#3 · huangyiirene · session_01J8VVAj7CvjkGXvgXzd6RZ7 Contract-review-claim: session_01J8VVAj7CvjkGXvgXzd6RZ7 · head 14487c5 · 2026-11-06T16:08Z The seat review runs at CONTRACT_REVIEW_TIER in an isolated subagent. No review seat ( |
|
domain:skills#3 · huangyiirene · session_01J8VVAj7CvjkGXvgXzd6RZ7 Contract reviewServed-tier: Inputs: card #30847 (body, triage 6679098621, claim comment), PR #30994 (body, two-file list), the net diff at the head against Check-runs at render time: every completed non-skipped run is ① Derived judgmentsNo accept-set changes. The diff touches no schema, no The published-surface change is the text of the
② Semver level
③ Boundary flags
④ Design judgment
True on
No undelivered door is taught. No route, grant key, L271–272 inside the derived-verb table. It reads correctly. "Never derive" is the resolver's present answer ( Findings
Not findings, for the record: the bin exists only when Implemented-by: VERDICT: FAIL |
…cts and updates eval case 5 The DELETE route comment names the condition (business-object rows), the pitfall says nothing lists or restores the bin over the API yet (sys_recycle_bin is apiEnabled: false), and eval case 5 expects the recycle-bin teaching instead of a hard delete with trackHistory or a lifecycle archive. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01J8VVAnsTJVz6nCb7n8NUJs
|
domain:skills#3 · huangyiirene · session_01J8VVAj7CvjkGXvgXzd6RZ7 Contract-review-claim: session_01J8VVAj7CvjkGXvgXzd6RZ7 · head 9a449ed · 2026-11-06T16:36Z Delta review against the FAIL at head 14487c5 (comment 6689544173). The delta is a merge of |
|
domain:skills#3 · huangyiirene · session_01J8VVAj7CvjkGXvgXzd6RZ7 Contract reviewServed-tier: This is a delta review. The previous record, on Inputs:
The merge. It brings in only
Check-runs on
① Derived judgmentsThere are still no accept-set changes. No schema, no The published-surface change is the text of the
② Semver level
③ Boundary flags
④ Design judgment
M1: resolved. Eval case 5 at the head:
S1: resolved, and still true. See ①. The comment now limits the bin to business-object rows on a by-id route. That is the exact reach of S2: resolved, and still true. "Nothing lists or restores it over the API yet" matches Pitfall 2, re-read whole. "Treating
No undelivered door, grant or route is taught. L271–272 still reads correctly inside the derived-verb table. "Declaring any derived verb in Findings: none. No must-fix and no should-fix remains. One note, not a finding. "Over the API" is narrower than the truth on Implemented-by: VERDICT: PASS |
|
domain:skills#3 · huangyiirene · session_01J8VVAj7CvjkGXvgXzd6RZ7 维护者速读
席位核对 — ACCEPT · domain:skills#3 · head
|
⛔ merge queue 构建失败 — 先分诊,再决定要不要重排队列构建 42259097933 红了。队列跑的是全量套件(PR 侧 CI 只跑 affected 子集), 分类: 失败的 job(日志抽取,best effort):
跨 PR 相同签名(24h,按失败测试文件聚合):
历史信号:
分诊清单:
Generated by Claude Code · merge-queue-triage workflow (#4859) |
|
domain:skills#3 · huangyiirene · session_01J8VVAj7CvjkGXvgXzd6RZ7 Dequeued, not this PR's failure. Queue build 42259097933 failed The ACCEPT (6690169452) and the PASS on this head (6690135496) still stand. No approval is on record yet, so the seat does not re-arm this PR itself: it needs one approval from |
Requested by Irene · project thread
Refs #30847
Clause-②: no
Metadata-protocol: none
The maintainer's standing order in this project (2026-11-03) waives the contract-review model tier that
dispatch-gatesmandates forskills/**(clause ①); this PR was developed below that tier, and the dispatching seat runs the contract review.维护者速读
skills/objectstack-api/SKILL.md三处:L48 路由表DELETE注释由 "hard delete" 改为 "business-object rows → recycle bin";派生动词说明restore/purge不派生的理由由"trash 面已退役"改为"回收站还没有 restore / purge 入口";陷阱第 2 条改写为:按 id 删除业务对象会把行保留在sys_recycle_bin(默认 30 天),multi: true删除、平台行、回收站上线前删除的行不在其中,目前没有任何 API 能列出或恢复它(sys_recycle_bin为apiEnabled: false),不要自造软删除。评测evals/endpoints-auth-routes.json第 5 例的期望同步改为回收站的说法。另加一条 changeset。Refs不写Fixes;restore / purge 入口、权限与 REST 路由的教学等 engine: snapshot deletes into the recycle bin, restore under original ids, purge, and the TTL reap (#3146 slice 3) #30237 的 restore 与 REST 入口 PR 落地后再补。skills/**),需要受管审批人在 GitHub 上 Approve 一次;之后席位落地。What changes
skills/objectstack-api/SKILL.md, three passages, each at its original line count:DELETE … # Delete record (hard delete)DELETE … # Delete record (business-object rows → recycle bin)restore/purgenever derive — the trash surface is retired."restore/purgenever derive: the recycle bin has no restore or purge door yet." (re-flowed inside its own three lines)DELETEis a hard delete — there is no recycle bin. For recoverability, use per-fieldtrackHistory… or alifecyclearchive policy instead of custom soft-delete logic."DELETEas final or as restorable. A by-id delete keeps a business object's rows in the recycle bin (sys_recycle_bin, 30 days by default; notmulti: truedeletes, platform rows or rows deleted before the bin existed); nothing lists or restores it over the API yet. No soft-delete."skills/objectstack-api/evals/endpoints-auth-routes.json, case 5 only (claim surface widened by the seat in rework round 1):expected_outputno longer saysrestore/purgenever derive "because DELETE is a hard delete; recoverability is per-fieldtrackHistoryor alifecyclearchive policy". It now says they never derive, a by-id delete of a business object already keeps its rows in the recycle bin (sys_recycle_bin), but nothing lists or restores them over the API yet, so there is no restore operation to add and no custom soft-delete to build.must_containswapstrackHistory/lifecycleforsys_recycle_bin/recycle bin;must_not_containkeeps'restore'..changeset/api-skill-delete-recycle-bin.md:'@objectstack/skills': patch, both declaration lines. Noskip-changesetlabel: askills/**diff ships in@objectstack/skills.Each claim, read off
main:packages/objectql/src/recycle-bin/capture.ts(PR feat(objectql,platform-objects): keep a by-id delete's rows in the recycle bin (ADR-0148) #30780):ObjectQL.delete's by-id branch (runByIdDelete,engine.ts≈L9514) snapshots the cascade set and writes onesys_recycle_binentry before the root row is removed. The RESTDELETE /data/{object}/:idreaches that branch (a scalarwhere.id).multi: true), not a platform object (sys_,cloud_,ai_,hasPlatformObjectPrefix), and a platform row the cascade reaches is left out of the snapshot. Rows deleted before PR feat(objectql,platform-objects): keep a by-id delete's rows in the recycle bin (ADR-0148) #30780 have no entry.packages/objectql/src/recycle-bin/retention.ts: host resolver, elseOS_RECYCLE_BIN_RETENTION_DAYS, elseRECYCLE_BIN_DEFAULT_RETENTION_DAYS(30), stamped aspurge_after;sys-recycle-bin.object.tsreaps on that deadline (ttl).sys-recycle-bin.object.tsdeclaresapiEnabled: false,apiMethods: [], so no generic data route reaches the bin.allowRestoreOwnDeleted/manageRecycleBininpackages/spec/src/security/permission.zod.tsare[PLANNED] … Not read yet;API_METHOD_DERIVATIONkeepsrestore/purgeatflag: () => false; no engine restore or REST route exists. So the skill names neither permission nor any door (engine: snapshot deletes into the recycle bin, restore under original ids, purge, and the TTL reap (#3146 slice 3) #30237 is still open).restore/purgestill never derive and are still stripped fromapiMethodswith a FROM → TO warning (LEGACY_API_METHOD_GUIDANCE,object.zod.ts), so that half of the L267 sentence stands.Dropped from the pitfall: the
enable.trashhistory (PR #30844 had already cut it) and the pointer totrackHistory/lifecyclearchive as the recoverability answer, which #30847 names as part of the wrong teaching.Budget.
skills/objectstack-api/SKILL.md: 441 → 441 lines, 20542 → 20646 bytes, 5141 → 5157 tokens (ceiling 6314, headroom 1157). The eval fixture keeps its line count (case 5's two lines change in place; measured, not ratcheted: 1498 → 1529 tokens). Net added lines inskills/**: 0. No ceiling row moves, so no deletion payment is owed.Serial. PR #30844 (seat 2) edited the same pitfall.
origin/mainat000a4c0d(with #30844) was merged into the branch, no rebase; the one conflict, pitfall 2, takes this PR's rewrite. Rework round 1 mergedorigin/mainc77dd17f(clean) before its commit.Why
#30847 (p2): since PR #30780 the skill contradicts shipped behaviour. An agent following it builds its own soft-delete, or tells a user a deleted record is gone when its snapshot sits in the bin. Triage audit 6679098621 asks for the "no recycle bin" correction now and the restore-door teaching once #30237's restore and REST-door PRs land; this PR is the first half, hence
Refs.Verification
Derived with
node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstackagainst the three-file diff, each command run undertimeout 900with stdin closed after a fullpnpm build, exit codes recorded first:211f3a99(first head, base1b3e22f0): 45 derived, 45 run, 45 exit 0.14487c50(after mergingorigin/main000a4c0d): 45 derived, 45 run, 45 exit 0.9a449ed9(the head, rework round 1, after mergingorigin/mainc77dd17f): 45 derived, 45 run, 45 exit 0.dispatch-gates --ran: 45 accounted, 0 NOT-MEASURED, 0 UNRUN.check-skills-token-ratchet: skills/objectstack-api/SKILL.md is 5157 tokens (ceiling 6314; headroom 1157).node scripts/check-commit-card-trailers.mjs --range origin/main..HEAD: 4 commits, exit 0, before each push.Ran lists:
card-30847/gates-{211f3a99,14487c50,9a449ed9}.txtin the project files.Ran list at 9a449ed
CI families (
Lint & Repo Gates,Test Core, the rest) are the PR's check-runs, not re-run locally.Human Minimum
packages/specholds no runtime logic.pnpm lintis CI's run (no source file in the diff).main, one pull request.packages/specnot touched.content/docs/references/,packages/*/CHANGELOG.mdorcontent/docs/releases/.🤖 Generated with Claude Code
https://claude.ai/code/session_01J8VVAnsTJVz6nCb7n8NUJs