You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Approvals inbox status filter: refusal for a non-string status prints "[object Object]", and the approvals docs page omits cancelled #30525
GET /api/v1/approvals/requests?status[$ne]=pending — the query parser hands readApprovalStatusFilter (packages/rest/src/approvals-routes.ts) an object. The route correctly answers 400 VALIDATION_ERROR and does not call the service, but the non-string arm builds the bad-value list with [String(raw)], so the message reads "[object Object]" is not an approval status. Read from the PR diff, not measured on a running server.
content/docs/automation/approvals.mdx (around L740) lists five request statuses; the object and the route accept six (cancelled is missing). Pre-existing; every listed value is accepted, the list is just short.
Expected
A non-string status is refused with a message that says the parameter must be a single string or a comma list of statuses, naming the allowed values; status code, envelope and "service not asked" unchanged. Pin it in rest-server-approvals-status-value.test.ts (the nested-object case already exists; assert the message).
The docs list matches APPROVAL_STATUSES (six values).
Out of scope
The console status picker (ApprovalsInboxPage.tsx) also lacks cancelled; that is ui lane (paused) and not part of this card.
Claim: PM loop round 1
Session: session_01Utp6CZMkHvuDeVYgTD73qF (seat) · dev card thread session_01Utp6CbAccy76jpUtQ9ZZX9
Account: os-bill
Branch: claude/project-thread-kjhqfe (the card thread's designated push branch, the recorded platform exception to claude/issue-<n>-<slug>)
Worktree: objectstack-issue-30525
Domain: domain:server
Seat: domain:server#4
File surface: packages/rest/src/approvals-routes.ts (readApprovalStatusFilter's non-string arm), rest-server-approvals-status-value.test.ts, content/docs/automation/approvals.mdx (the status list), one changeset. ⛔ packages/spec/**, docs/adr/**, .claude/**, repo-root AGENTS.md, ui/**, skills/** (stop on breach; explain in the report)
Container & model: S, mode:thread, model: default judgment tier (opus) — dispatch-gates --tier: no path-derived mandate, effort: default
Clause-②: no — the same requests are refused; only the message and a docs list change
Metadata-protocol: none
Responsibility: the refusal for a non-string status prints "[object Object]"; the approvals docs page lists five of six statuses | none: contract review record 6659996154 should-fixes 1 and 2 | integrators reading the 400 message or the docs
Thread-read: none
Premise: holds (PR #30491 merged 2026-11-05T15:26Z, 75bbebb27)
Serial constraints cleared: seat 5 pinged; seat 6's #30509 does not touch approvals-routes.ts (seat 6, 14:22Z).
Dispatch order: /mnt/project-files/server-seat4/dispatch-30525.md (project shared folder). Ruling section: contract review record 6659996154 of PR #30491. Dispatched on the maintainer's 「任务很多,车道尽量跑满并发」. Fixes #30525.
Dev card thread session_01Utp6CbAccy76jpUtQ9ZZX9, branch claude/project-thread-kjhqfe (restarted from main75bbebb after #30491 merged), Claim 6661950425. Draft PR #30569 (author objectstack-fleet[bot]), head b6b000c5.
{
"issue": 30525,
"status": "done",
"branch": "claude/project-thread-kjhqfe",
"pr": "https://github.com/objectstack-ai/objectstack/pull/30569",
"session": "session_01Utp6CbAccy76jpUtQ9ZZX9",
"premise_still_valid": true,
"summary": "readApprovalStatusFilter (packages/rest/src/approvals-routes.ts) gets its own non-string arm: a status the query parser built into an object (?status[$ne]=pending) is refused with 'The \"status\" query parameter must be one status, or several separated by commas, given as plain text. Allowed values: pending, approved, rejected, recalled, returned, cancelled.' instead of quoting \"[object Object]\". Same 400 VALIDATION_ERROR nested envelope, service not asked; the string path is unchanged. content/docs/automation/approvals.mdx 'Statuses in full' now lists all six APPROVAL_STATUSES, with one clause on cancelled and cancel_reason.",
"tests": "rest-server-approvals-status-value.test.ts nested-object case now asserts the exact message, no [object Object], no data beside the error, and neither listRequests nor countRequests ran; file 16/16. Ablation via scripts/ablation-replace.mjs making the arm unreachable (typeof raw !== 'string' -> === 'symbol', blob 8fecd091 -> 9dde4c15): that case fails (string path throws on the object, route answers 500), 15 pass; restored, git diff HEAD empty. @objectstack/rest vitest: 393 files, 7641 passed / 352 skipped. pnpm --filter @objectstack/rest run typecheck: exit 0.",
"gates": "dispatch-gates --commands --repo objectstack-ai/objectstack at b6b000c5: 88 commands, each recorded command :: exit code to a file, after a full turbo run build --filter='!@objectstack/docs' (exit 0). All 88 exit 0. --ran: 88 derived, 88 run, 0 NOT-MEASURED, 0 UNRUN. pnpm lint: exit 0. PR check-runs: in_progress at report time. Records: project folder server-seat4/30525/gates-cmds.txt, gates-ran-clean.txt.",
"dogfood_battery": "n/a — no `!` in the PR title and no (narrowing) arm",
"line_budget": "41 changed lines (+35 / -6) across 4 files, under the 3000 human-merge threshold",
"files_changed": [
"packages/rest/src/approvals-routes.ts",
"packages/rest/src/rest-server-approvals-status-value.test.ts",
"content/docs/automation/approvals.mdx",
".changeset/30525-approvals-status-non-string-message.md"
],
"deviations": [
"The full workspace build before the gates ran outside os-verify-lock.",
"The remote branch had been deleted after #30491 merged, so the restarted branch was pushed as a new branch (no force push needed).",
"Reviewer request and assignee not written (order: no MCP write; relay pr_create sent no assignees)."
],
"mcp_calls": "0 — no GitHub MCP call of any kind",
"api_writes": "3 — git push (branch), relay pr_create (#30569, 4137 bytes sent = stored), this os-dev-report via post-stamped",
"open_questions": [],
"security_findings": "none",
"out_of_scope_findings": [
"class: none filed · carrier: #30525 body · console status picker (ApprovalsInboxPage.tsx) still lacks cancelled; ui lane, already named out of scope on the card."
]
}
Activity
objectstack-fleet commentedon Nov 5, 2026
triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U
Path: none
Triage: audit · p3 kept ·
domain:server· 2026-11-05T15:05Z⛔ Not a claim.
[object Object]for a non-stringstatus. Wording only.Generated by Claude Code
objectstack-fleet commentedon Nov 5, 2026
domain:server#4 · os-bill · session_01Utp6CZMkHvuDeVYgTD73qF
Claim: PM loop round 1
Session:
session_01Utp6CZMkHvuDeVYgTD73qF(seat) · dev card threadsession_01Utp6CbAccy76jpUtQ9ZZX9Account:
os-billBranch:
claude/project-thread-kjhqfe(the card thread's designated push branch, the recorded platform exception toclaude/issue-<n>-<slug>)Worktree:
objectstack-issue-30525Domain:
domain:serverSeat:
domain:server#4File surface:
packages/rest/src/approvals-routes.ts(readApprovalStatusFilter's non-string arm),rest-server-approvals-status-value.test.ts,content/docs/automation/approvals.mdx(the status list), one changeset. ⛔packages/spec/**,docs/adr/**,.claude/**, repo-rootAGENTS.md,ui/**,skills/**(stop on breach; explain in the report)Container & model:
S,mode:thread,model: default judgment tier (opus) — dispatch-gates --tier: no path-derived mandate,effort: defaultClause-②: no — the same requests are refused; only the message and a docs list change
Metadata-protocol: none
Responsibility:
the refusal for a non-string status prints "[object Object]"; the approvals docs page lists five of six statuses | none: contract review record 6659996154 should-fixes 1 and 2 | integrators reading the 400 message or the docsThread-read: none
Premise: holds (PR #30491 merged 2026-11-05T15:26Z,
75bbebb27)Serial constraints cleared: seat 5 pinged; seat 6's #30509 does not touch
approvals-routes.ts(seat 6, 14:22Z).Dispatch order:
/mnt/project-files/server-seat4/dispatch-30525.md(project shared folder). Ruling section: contract review record 6659996154 of PR #30491. Dispatched on the maintainer's 「任务很多,车道尽量跑满并发」.Fixes #30525.Posted 2026-11-05T15:28Z.
objectstack-fleet commentedon Nov 5, 2026
domain:server#4 · os-bill · session_01Utp6CZMkHvuDeVYgTD73qF
os-dev-report
Dev card thread
session_01Utp6CbAccy76jpUtQ9ZZX9, branchclaude/project-thread-kjhqfe(restarted frommain75bbebb after #30491 merged), Claim 6661950425. Draft PR #30569 (authorobjectstack-fleet[bot]), headb6b000c5.{ "issue": 30525, "status": "done", "branch": "claude/project-thread-kjhqfe", "pr": "https://github.com/objectstack-ai/objectstack/pull/30569", "session": "session_01Utp6CbAccy76jpUtQ9ZZX9", "premise_still_valid": true, "summary": "readApprovalStatusFilter (packages/rest/src/approvals-routes.ts) gets its own non-string arm: a status the query parser built into an object (?status[$ne]=pending) is refused with 'The \"status\" query parameter must be one status, or several separated by commas, given as plain text. Allowed values: pending, approved, rejected, recalled, returned, cancelled.' instead of quoting \"[object Object]\". Same 400 VALIDATION_ERROR nested envelope, service not asked; the string path is unchanged. content/docs/automation/approvals.mdx 'Statuses in full' now lists all six APPROVAL_STATUSES, with one clause on cancelled and cancel_reason.", "tests": "rest-server-approvals-status-value.test.ts nested-object case now asserts the exact message, no [object Object], no data beside the error, and neither listRequests nor countRequests ran; file 16/16. Ablation via scripts/ablation-replace.mjs making the arm unreachable (typeof raw !== 'string' -> === 'symbol', blob 8fecd091 -> 9dde4c15): that case fails (string path throws on the object, route answers 500), 15 pass; restored, git diff HEAD empty. @objectstack/rest vitest: 393 files, 7641 passed / 352 skipped. pnpm --filter @objectstack/rest run typecheck: exit 0.", "gates": "dispatch-gates --commands --repo objectstack-ai/objectstack at b6b000c5: 88 commands, each recorded command :: exit code to a file, after a full turbo run build --filter='!@objectstack/docs' (exit 0). All 88 exit 0. --ran: 88 derived, 88 run, 0 NOT-MEASURED, 0 UNRUN. pnpm lint: exit 0. PR check-runs: in_progress at report time. Records: project folder server-seat4/30525/gates-cmds.txt, gates-ran-clean.txt.", "dogfood_battery": "n/a — no `!` in the PR title and no (narrowing) arm", "line_budget": "41 changed lines (+35 / -6) across 4 files, under the 3000 human-merge threshold", "files_changed": [ "packages/rest/src/approvals-routes.ts", "packages/rest/src/rest-server-approvals-status-value.test.ts", "content/docs/automation/approvals.mdx", ".changeset/30525-approvals-status-non-string-message.md" ], "deviations": [ "The full workspace build before the gates ran outside os-verify-lock.", "The remote branch had been deleted after #30491 merged, so the restarted branch was pushed as a new branch (no force push needed).", "Reviewer request and assignee not written (order: no MCP write; relay pr_create sent no assignees)." ], "mcp_calls": "0 — no GitHub MCP call of any kind", "api_writes": "3 — git push (branch), relay pr_create (#30569, 4137 bytes sent = stored), this os-dev-report via post-stamped", "open_questions": [], "security_findings": "none", "out_of_scope_findings": [ "class: none filed · carrier: #30525 body · console status picker (ApprovalsInboxPage.tsx) still lacks cancelled; ui lane, already named out of scope on the card." ] }Report taken 2026-11-05T16:20Z.
Generated by Claude Code
objectstack-fleet commentedon Nov 5, 2026
domain:server#4 · os-bill · session_01Utp6CZMkHvuDeVYgTD73qF
Landed · PR #30569 · card closed
739c97273;Fixes #30525closes this card. Seat record 6663696039 (not BREAKING, not governed,Clause-②: no).mainsourcepackages/rest/src/approvals-routes.ts:115if (typeof raw !== 'string') {The card's label
pm:dispatchedand theos-billassignee come off with this comment.Posted 2026-11-05T17:07Z.