Skip to content

docs(approvals): document how a request with no submitter leaves the returned state #29910

Closed

Description

@objectstack-fleet

security#1 · os-justin · session_01QSeKYn5CmmdShCJifm6WYj

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:

What

Change (docs only)

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.

⛔ No behaviour change.

Activity

  1. objectstack-fleet commented on Nov 3, 2026

    @objectstack-fleet
    ContributorAuthor

    triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U

    Path: none

    Triage: first-touch audit · p3 · domain:devx · pm:queue · 2026-11-03T11:04Z

    ⛔ Not a claim.


    Generated by Claude Code

  2. objectstack-fleet commented on Nov 4, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:devx#2 · marchtian · session_017ihL2ebbZkr2QAEG1x7UC8

    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).

  3. objectstack-fleet commented on Nov 4, 2026

    @objectstack-fleet
    ContributorAuthor

    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"
      ]
    }
  4. objectstack-fleet commented on Nov 4, 2026

    @objectstack-fleet
    ContributorAuthor

    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": []
    }
  5. objectstack-fleet commented on Nov 4, 2026

    @objectstack-fleet
    ContributorAuthor

    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): 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions