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
docs(approvals): document how a request with no submitter leaves the returned state #29910
Maintainer ruling. In session session_01QSeKYn5CmmdShCJifm6WYj on 2026-11-03 the maintainer accepted the seat's analysis, which had been reviewed at CONTRACT_REVIEW_TIER first. Verbatim: 「第三批 同意」. For item 5 the analysis offered three options:
D: leave the behaviour as it is and document the way out (chosen);
A: refuse send-back on a request with no submitter (not chosen, because an author's declared revise edge would turn into a runtime refusal);
In the approvals guide, and next to the sendBack / recall contract docblocks, state that path for requests with no submitter. Say what an author should put on the revise branch of a flow started by a user-less trigger.
Claim: PM loop round 1
Session: session_017ihL2ebbZkr2QAEG1x7UC8
Account: marchtian
Branch: claude/issue-29910-no-submitter-returned-docs
Worktree: objectstack-issue-29910
Domain: domain:devx
Seat: domain:devx#2
File surface: the approvals guide (content/docs/automation/approvals.mdx, and content/docs/capabilities/approvals.mdx only if it is the guide that teaches send-back/recall), and docblock prose beside sendBack / recall in packages/spec/src/contracts/approval-service.ts (comments only). ⛔ No behaviour change, no schema or type change; any generated reference page follows its generator, never a hand edit.
Container & model: S, mode:subagent, model: default tier (dispatch-gates --tier: no path-derived mandate), effort: medium
Clause-②: no
Metadata-protocol: none
Responsibility: n/a — not a defect card (the maintainer chose D, document the way out, in 「第三批 同意」 as quoted on this card)
Thread-read: 6602125866
Premise: holds (origin/main: the recall input docblock still says a returned request is recallable by the submitter alone, approval-service.ts ~L662–667; no guide states the no-submitter path)
Serial constraints cleared: no open PR or live Claim: names these files. The spec docblock half is a spec-package touch, so this PR owes a full independent review before merge (this account's standing rule for spec changes).
{
"issue": 29910,
"status": "done",
"branch": "claude/issue-29910-no-submitter-returned-docs",
"pr": "https://github.com/objectstack-ai/objectstack/pull/30137",
"head": "74870830a7908f70235f91a0a11b07fef65dd41b",
"premise_still_valid": true,
"files_changed": [
".changeset/29910-no-submitter-returned-docs.md",
"content/docs/automation/approvals.mdx",
"packages/spec/src/contracts/approval-service.ts"
],
"line_budget": "38 changed lines (+37 / -1) across 3 files vs a budget of about 40 net",
"changeset": "@objectstack/spec patch: the docblock text ships in packages/spec/dist/contracts/index.d.ts and index.d.mts (positive control: an existing sentence from the same docblock is found in the same two files), so this is a published comment-only change, not skip-changeset",
"comments_only_proof": "TypeScript scanner token stream of approval-service.ts with comments skipped: 1420 = 1420 tokens, identical at 987ff33b and HEAD; control (actorId: string changed to number) reports not identical",
"call_sites": [
"packages/plugins/plugin-approvals/src/approval-node.ts:107-111 runTriggerUser returns null when the trigger resolved no user",
"packages/plugins/plugin-approvals/src/approval-node.ts:199 submitterId: runTriggerUser(context), on every round's openNodeRequest",
"packages/plugins/plugin-approvals/src/approval-service.ts:6041 sendBack admits a pending approver or a system context, no submitter test",
"packages/plugins/plugin-approvals/src/approval-service.ts:6278-6312 assertReviseEdge: the revise edge must exist and target an approval_revise node",
"packages/plugins/plugin-approvals/src/approval-revise-node.ts:89-98 the window arms nothing; only resubmit or recall ends it",
"packages/plugins/plugin-approvals/src/approval-service.ts:1114-1117 actsAsSubmitter is false for every actor when submitter_id is null",
"packages/plugins/plugin-approvals/src/approval-service.ts:5613-5618 recall: overrideAdmits needs status pending, so nobody recalls a returned request with no submitter",
"packages/plugins/plugin-approvals/src/approval-service.ts:6202 resubmit admits context.isSystem on a returned request",
"packages/plugins/plugin-approvals/src/approval-service.ts:6241-6248 the resubmit resume carries no resumedBy; services/service-automation/src/run-resume.ts:326-328 so the run context is not switched and round N+1 opens with no submitter",
"packages/plugins/plugin-approvals/src/approval-service.ts:2111-2113 isOverrideActor: context.isSystem always passes, so the system or the override actor recalls the new pending round (5613-5614)",
"packages/plugins/plugin-approvals/src/approval-service.test.ts:6403-6423 pins: override and system recall a pending no-submitter request; system resubmits a returned one",
"packages/plugins/plugin-approvals/src/sys-approval-request.object.ts:766-778 and packages/rest/src/approvals-routes.ts:518-523 no console button and no REST door grants the system context"
],
"gates": {
"derived": "95 commands from dispatch-gates --commands at 74870830",
"first_pass": "88 exit 0, 7 exit 3 (PREREQUISITE NOT MET: shallow clone, unbuilt workspace packages)",
"after_unshallow_and_full_build": "the 7 rerun, all exit 0; full build VERDICT command-exit 0, 119/119 tasks",
"ran_reconciliation": "95 derived, 95 run, 0 NOT-MEASURED, a DERIVED zero, all 95 recorded an exit code",
"spec_build": "exit 0 (VERDICT command-exit 0)",
"spec_check_generated": "exit 0 at 4096 MB heap, all 14 up to date; the first run at the default heap exit 1 from a tsc heap OOM in check:test-typecheck, no stale artifact",
"spec_typecheck": "exit 0",
"check_dev_prereqs": "exit 0",
"check_commit_card_trailers": "exit 0",
"ci_check_runs": "in_progress at report time; not waited on"
},
"deviations": [
"the spec vitest suite was not run locally (non-comment tokens are unchanged); it is left to CI Test Core",
"git fetch --unshallow origin main was run in the shared object store, because check-plugin-teardown-shape --self-test asked for it"
],
"dogfood_battery": "n/a: no ! in the PR title and no (narrowing) arm",
"mcp_calls": "0",
"api_writes": "2: one relay pr_create (repository_dispatch, PR 30137) and this comment via post-stamped",
"security_findings": "none",
"out_of_scope_findings": [
"class: none, noted only: a system-context resubmit has no public door (no console action, and the REST resubmit route passes the caller's context), so the documented way out needs server-side code. carrier: seat, noted in the PR's Acceptance notes, not filed"
]
}
{
"issue": 29910,
"round": 2,
"status": "done",
"pr": "https://github.com/objectstack-ai/objectstack/pull/30137",
"head": "f4d534bd32cb18f6a350e67a7eb88469d78b53d2",
"review_record": 6635054232,
"fixes": {
"S1": "reissueContinuation docblock: resubmit is 'by the submitter or a system context only'",
"S2": "the author rule (sendBack docblock and guide) is scoped to triggers that never carry a user (schedule, time-relative, api); a record-change flow fired by a system write: the sent-back round waits for a server-side resubmit, or an operator cancel discards the run and leaves the request returned",
"S3": "recall docblock, returned arm: the run is cancelled (the revise window has no reject edge)",
"nit": "the guide says a system-context resubmit must supply an actorId"
},
"call_sites": [
"packages/services/service-automation/src/runtime-identity.ts:508-514 a record-change flow is user-less when fired by a write that carried no user",
"packages/runtime/src/domains/automation.ts:4256 POST /automation/:name/runs/:runId/cancel, gated on the platform-operator rung",
"packages/services/service-automation/src/run-resume.ts:883 cancelRun has no resumeAuthority gate",
"packages/plugins/plugin-approvals/src/approval-service.ts:7851 the dead-run sweep scans status pending only; 7110-7116 inspectStrandedRequests reports and never rewrites, so a cancelled run leaves the row returned",
"packages/plugins/plugin-approvals/src/approval-service.ts:5683-5694 a revise-window recall calls cancelRun",
"packages/plugins/plugin-approvals/src/approval-service.ts:2259-2261 resolveActor throws VALIDATION_FAILED for a system context with no actorId"
],
"comments_only_proof": "TypeScript scanner token stream of approval-service.ts with comments skipped: identical (1420 tokens) at 987ff33b vs f4d534bd and at 74870830 vs f4d534bd; the mutation control reports not identical",
"changeset": "unchanged",
"gates": {
"derived": "95 commands at f4d534bd, the same set as round 1",
"run": "95 run, all exit 0, after a spec rebuild (VERDICT command-exit 0)",
"ran_reconciliation": "95 derived, 95 run, 0 NOT-MEASURED, a DERIVED zero",
"spec_check_generated": "exit 0 (4096 MB heap), 14/14 up to date",
"spec_typecheck": "exit 0",
"check_commit_card_trailers": "exit 0"
},
"line_budget": "54 changed lines (+50 / -4) across 3 files; over the ~40 budget because of the review's S2 and nit text",
"deviations": [
"no merge of origin/main in this round (the PR does not conflict)",
"the PR body's Verification section still names head 74870830, and the body has not been rewritten (the dev writes it once); the seat may restate the head"
],
"mcp_calls": "0",
"api_writes": "1: this comment via post-stamped; plus one git push (f4d534bd)",
"security_findings": "none",
"out_of_scope_findings": []
}
Landed · PR #30137 merged as 471add32df · 2026-11-04T17:01Z. Ruling D (document the way out, no behaviour change): the sendBack / recall / resubmit / reissueContinuation docblocks and the approvals guide now say how a request returned to a run with no submitter moves on, and what an operator's cancelRun does. Contract review: Fable PASS 6635054232 and delta PASS 6635874795; ACCEPT 6636096392. '@objectstack/spec': patch. The card closed through Fixes; pm:dispatched comes off in this stroke.
Activity
objectstack-fleet commentedon Nov 3, 2026
triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U
Path: none
Triage: first-touch audit · p3 ·
domain:devx·pm:queue· 2026-11-03T11:04Z⛔ Not a claim.
returned, whererecallreaches only the submitter ([Decision] Override-recall of areturnedapproval: an ADR-0044 side effect to retire, or a capability to keep? The gate, the prose and the viewer flag disagree three ways #12775). The maintainer chose D (document) in 「第三批 同意」. Docs only, so p3.Generated by Claude Code
objectstack-fleet commentedon Nov 4, 2026
domain:devx#2 · marchtian · session_017ihL2ebbZkr2QAEG1x7UC8
Claim: PM loop round 1
Session:
session_017ihL2ebbZkr2QAEG1x7UC8Account:
marchtianBranch:
claude/issue-29910-no-submitter-returned-docsWorktree:
objectstack-issue-29910Domain:
domain:devxSeat:
domain:devx#2File surface: the approvals guide (
content/docs/automation/approvals.mdx, andcontent/docs/capabilities/approvals.mdxonly if it is the guide that teaches send-back/recall), and docblock prose besidesendBack/recallinpackages/spec/src/contracts/approval-service.ts(comments only). ⛔ No behaviour change, no schema or type change; any generated reference page follows its generator, never a hand edit.Container & model:
S,mode:subagent,model: default tier (dispatch-gates --tier: no path-derived mandate),effort: mediumClause-②: no
Metadata-protocol: none
Responsibility: n/a — not a defect card (the maintainer chose D, document the way out, in 「第三批 同意」 as quoted on this card)
Thread-read: 6602125866
Premise: holds (
origin/main: therecallinput docblock still says areturnedrequest is recallable by the submitter alone,approval-service.ts~L662–667; no guide states the no-submitter path)Serial constraints cleared: no open PR or live
Claim:names these files. The spec docblock half is a spec-package touch, so this PR owes a full independent review before merge (this account's standing rule for spec changes).objectstack-fleet commentedon Nov 4, 2026
domain:devx#2 · marchtian · session_017ihL2ebbZkr2QAEG1x7UC8
os-dev-report
{ "issue": 29910, "status": "done", "branch": "claude/issue-29910-no-submitter-returned-docs", "pr": "https://github.com/objectstack-ai/objectstack/pull/30137", "head": "74870830a7908f70235f91a0a11b07fef65dd41b", "premise_still_valid": true, "files_changed": [ ".changeset/29910-no-submitter-returned-docs.md", "content/docs/automation/approvals.mdx", "packages/spec/src/contracts/approval-service.ts" ], "line_budget": "38 changed lines (+37 / -1) across 3 files vs a budget of about 40 net", "changeset": "@objectstack/spec patch: the docblock text ships in packages/spec/dist/contracts/index.d.ts and index.d.mts (positive control: an existing sentence from the same docblock is found in the same two files), so this is a published comment-only change, not skip-changeset", "comments_only_proof": "TypeScript scanner token stream of approval-service.ts with comments skipped: 1420 = 1420 tokens, identical at 987ff33b and HEAD; control (actorId: string changed to number) reports not identical", "call_sites": [ "packages/plugins/plugin-approvals/src/approval-node.ts:107-111 runTriggerUser returns null when the trigger resolved no user", "packages/plugins/plugin-approvals/src/approval-node.ts:199 submitterId: runTriggerUser(context), on every round's openNodeRequest", "packages/plugins/plugin-approvals/src/approval-service.ts:6041 sendBack admits a pending approver or a system context, no submitter test", "packages/plugins/plugin-approvals/src/approval-service.ts:6278-6312 assertReviseEdge: the revise edge must exist and target an approval_revise node", "packages/plugins/plugin-approvals/src/approval-revise-node.ts:89-98 the window arms nothing; only resubmit or recall ends it", "packages/plugins/plugin-approvals/src/approval-service.ts:1114-1117 actsAsSubmitter is false for every actor when submitter_id is null", "packages/plugins/plugin-approvals/src/approval-service.ts:5613-5618 recall: overrideAdmits needs status pending, so nobody recalls a returned request with no submitter", "packages/plugins/plugin-approvals/src/approval-service.ts:6202 resubmit admits context.isSystem on a returned request", "packages/plugins/plugin-approvals/src/approval-service.ts:6241-6248 the resubmit resume carries no resumedBy; services/service-automation/src/run-resume.ts:326-328 so the run context is not switched and round N+1 opens with no submitter", "packages/plugins/plugin-approvals/src/approval-service.ts:2111-2113 isOverrideActor: context.isSystem always passes, so the system or the override actor recalls the new pending round (5613-5614)", "packages/plugins/plugin-approvals/src/approval-service.test.ts:6403-6423 pins: override and system recall a pending no-submitter request; system resubmits a returned one", "packages/plugins/plugin-approvals/src/sys-approval-request.object.ts:766-778 and packages/rest/src/approvals-routes.ts:518-523 no console button and no REST door grants the system context" ], "gates": { "derived": "95 commands from dispatch-gates --commands at 74870830", "first_pass": "88 exit 0, 7 exit 3 (PREREQUISITE NOT MET: shallow clone, unbuilt workspace packages)", "after_unshallow_and_full_build": "the 7 rerun, all exit 0; full build VERDICT command-exit 0, 119/119 tasks", "ran_reconciliation": "95 derived, 95 run, 0 NOT-MEASURED, a DERIVED zero, all 95 recorded an exit code", "spec_build": "exit 0 (VERDICT command-exit 0)", "spec_check_generated": "exit 0 at 4096 MB heap, all 14 up to date; the first run at the default heap exit 1 from a tsc heap OOM in check:test-typecheck, no stale artifact", "spec_typecheck": "exit 0", "check_dev_prereqs": "exit 0", "check_commit_card_trailers": "exit 0", "ci_check_runs": "in_progress at report time; not waited on" }, "deviations": [ "the spec vitest suite was not run locally (non-comment tokens are unchanged); it is left to CI Test Core", "git fetch --unshallow origin main was run in the shared object store, because check-plugin-teardown-shape --self-test asked for it" ], "dogfood_battery": "n/a: no ! in the PR title and no (narrowing) arm", "mcp_calls": "0", "api_writes": "2: one relay pr_create (repository_dispatch, PR 30137) and this comment via post-stamped", "security_findings": "none", "out_of_scope_findings": [ "class: none, noted only: a system-context resubmit has no public door (no console action, and the REST resubmit route passes the caller's context), so the documented way out needs server-side code. carrier: seat, noted in the PR's Acceptance notes, not filed" ] }objectstack-fleet commentedon Nov 4, 2026
domain:devx#2 · marchtian · session_017ihL2ebbZkr2QAEG1x7UC8
os-dev-report
{ "issue": 29910, "round": 2, "status": "done", "pr": "https://github.com/objectstack-ai/objectstack/pull/30137", "head": "f4d534bd32cb18f6a350e67a7eb88469d78b53d2", "review_record": 6635054232, "fixes": { "S1": "reissueContinuation docblock: resubmit is 'by the submitter or a system context only'", "S2": "the author rule (sendBack docblock and guide) is scoped to triggers that never carry a user (schedule, time-relative, api); a record-change flow fired by a system write: the sent-back round waits for a server-side resubmit, or an operator cancel discards the run and leaves the request returned", "S3": "recall docblock, returned arm: the run is cancelled (the revise window has no reject edge)", "nit": "the guide says a system-context resubmit must supply an actorId" }, "call_sites": [ "packages/services/service-automation/src/runtime-identity.ts:508-514 a record-change flow is user-less when fired by a write that carried no user", "packages/runtime/src/domains/automation.ts:4256 POST /automation/:name/runs/:runId/cancel, gated on the platform-operator rung", "packages/services/service-automation/src/run-resume.ts:883 cancelRun has no resumeAuthority gate", "packages/plugins/plugin-approvals/src/approval-service.ts:7851 the dead-run sweep scans status pending only; 7110-7116 inspectStrandedRequests reports and never rewrites, so a cancelled run leaves the row returned", "packages/plugins/plugin-approvals/src/approval-service.ts:5683-5694 a revise-window recall calls cancelRun", "packages/plugins/plugin-approvals/src/approval-service.ts:2259-2261 resolveActor throws VALIDATION_FAILED for a system context with no actorId" ], "comments_only_proof": "TypeScript scanner token stream of approval-service.ts with comments skipped: identical (1420 tokens) at 987ff33b vs f4d534bd and at 74870830 vs f4d534bd; the mutation control reports not identical", "changeset": "unchanged", "gates": { "derived": "95 commands at f4d534bd, the same set as round 1", "run": "95 run, all exit 0, after a spec rebuild (VERDICT command-exit 0)", "ran_reconciliation": "95 derived, 95 run, 0 NOT-MEASURED, a DERIVED zero", "spec_check_generated": "exit 0 (4096 MB heap), 14/14 up to date", "spec_typecheck": "exit 0", "check_commit_card_trailers": "exit 0" }, "line_budget": "54 changed lines (+50 / -4) across 3 files; over the ~40 budget because of the review's S2 and nit text", "deviations": [ "no merge of origin/main in this round (the PR does not conflict)", "the PR body's Verification section still names head 74870830, and the body has not been rewritten (the dev writes it once); the seat may restate the head" ], "mcp_calls": "0", "api_writes": "1: this comment via post-stamped; plus one git push (f4d534bd)", "security_findings": "none", "out_of_scope_findings": [] }objectstack-fleet commentedon Nov 4, 2026
domain:devx#2 · marchtian · session_017ihL2ebbZkr2QAEG1x7UC8
Landed · PR #30137 merged as
471add32df· 2026-11-04T17:01Z. Ruling D (document the way out, no behaviour change): thesendBack/recall/resubmit/reissueContinuationdocblocks and the approvals guide now say how a request returned to a run with no submitter moves on, and what an operator'scancelRundoes. Contract review: Fable PASS 6635054232 and delta PASS 6635874795; ACCEPT 6636096392.'@objectstack/spec': patch. The card closed throughFixes;pm:dispatchedcomes off in this stroke.