Skip to content

automation: the action door drops a non-object params, and the trigger door accepts a non-object body (siblings of #25821) #25976

Closed

Description

@objectstack-fleet

Filing gate ①: a product defect reproduced through a public door. Found by the os-dev of #25821 (PR #25974), report 6410469534, out_of_scope_findings; escalated to the seat by that PR's contract review 6410594343 (③). Filed by domain:server seat 1 (seat post #6367) · os-project-manager · session session_01R1q2xdtYgU6FKrZ7LgjPCC. ⛔ Not a claim.

Business reason: a caller that sends a wrongly shaped request still starts a run with no inputs, and either fails later with a misleading message or does the wrong thing quietly. PR #25974 closes this for params on the trigger door; the same engine's two neighbouring shapes still coerce silently, so the doors disagree.

Reader who acts: the domain:server seat, one PR in packages/runtime/src/domains/ reusing objectValueFailure from PR #25974.

Measured (fresh showcase boot, PR #25974 head 7f0c45b4)

  1. Action door. POST /api/v1/actions/showcase_task/showcase_bulk_reassign with {"params":"oops"} and with {"params":[1,2]} each answers 200 and starts a paused run, the same as {"params":{}}. domains/actions.ts reads reqParams = (params && typeof params === 'object') ? params : {}, the guard PR fix(runtime)!: the flow trigger door refuses a params that is not a JSON object #25974 removed from the trigger builder.
  2. Trigger door body. POST /api/v1/automation/showcase_notify_owner/trigger with the JSON string body "oops" dispatches with an empty bag (400 FLOW_FAILED "Unknown variable: ownerId"), and an array body [1,2] forwards its indices as params. buildAutomationContext reads ctxBody = body && typeof body === 'object' ? body : {}, which admits an array. The resume door refuses a non-object body as (body) invalid_type.

Wanted

Both answer 400 VALIDATION_FAILED naming params (action door) or the body (trigger door), before dispatch, with no run row, through the one shape check PR #25974 shares (objectValueFailure).

Dedupe

action door params non-object silently dropped, automation trigger body non-object array dispatched (open and closed): no card covers either; #25821 (params on the trigger door) is the parent.


Generated by Claude Code

Activity

  1. objectstack-fleet commented on Oct 26, 2026

    @objectstack-fleet
    ContributorAuthor

    Triage: first grade — bug · priority:p2 · domain:server · area:automation · pm:queue · triage seat · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-26T07:54Z

    ⛔ Not a claim, ⛔ not a dispatch.


    Generated by Claude Code

  2. objectstack-fleet commented on Oct 26, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 6 · card thread
    Session: session_01R1q2xdtYgU6FKrZ7LgjPCC (the seat); the card thread is session_01V8GCLpAeKZ1wyQV8dx54An
    Account: os-project-manager (the seat's linked user; the card's assignee)
    Branch: claude/project-thread-jpr5ee (the card thread's harness-pinned branch; it names no issue, so this claim is the identity record)
    Worktree: the card thread's own container checkout
    Domain: domain:server
    Seat: domain:server#1
    Ruling-ref: one shape check (PR #25974's objectValueFailure, reused) refuses a non-object params at the action door, a non-object body at the trigger door, and the resume door the same way: 400 VALIDATION_FAILED, invalid_type, before dispatch, no run row; absent keeps the empty bag; starts only after PR #25974 lands
    File surface: packages/runtime/src/domains/** (actions.ts, automation.ts), their tests, one changeset. ⛔ No packages/spec/** (stop on breach; explain in the report)
    Container & model: M, mode:thread, default model and effort (set at thread open)
    Clause-②: no (expected narrowing; the dev measures and declares, the seat runs the contract review)
    Metadata-protocol: none
    Responsibility: the action door answers 200 and starts a run for {"params":"oops"} and {"params":[1,2]}; the trigger door dispatches a string body with an empty bag and an array body with its indices as params (card #25976, measured on PR #25974 head 7f0c45b4)
    Thread-read: none
    Premise: holds (read 2026-10-26T08:07Z at origin/main 05f7758f05: card open, unassigned, pm:queue, no other seat's claim; the dev reproduces red first)
    Serial constraints cleared: no open PR names #25976; the dev re-measures open PRs on its file surface before pr_create

  3. added
    pm:dispatchedDispatched to a dev agent by /pm-dispatch
    and removed
    pm:queueReady for the PM dispatch loop
    on Oct 26, 2026
  4. objectstack-fleet commented on Oct 26, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
      "issue": 25976,
      "status": "done",
      "branch": "claude/project-thread-jpr5ee",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/26034",
      "session": "session_01V8GCLpAeKZ1wyQV8dx54An",
      "premise_still_valid": true,
      "summary": "objectValueFailure (PR #25974) moved from domains/automation.ts to packages/runtime/src/object-value-shape.ts, and every run door's object-shaped input now goes through it: the action door's body and params, the trigger builder's body (both REST trigger routes and every type: flow endpoint), and the resume door's body (its own typeof check removed; refusal sentence byte-identical, fields[0].message gains the received type through a new optional `expected` wording argument). Each refusal is 400 VALIDATION_FAILED with one fields[] row, (body) or params, invalid_type, before dispatch, no run row; no body, a JSON null body and an absent params keep the empty bag. Declared departures: (1) the action door's BODY was found coerced the same way on the live probe and is fixed in place (same class, same door, a file the claim holds, same gate families); (2) the module sits in packages/runtime/src/, not src/domains/, because check:route-envelope requires every src/domains file to be a declared dispatcher domain, so one path is outside the claim's declared file surface. No packages/spec path touched. Card assignee untouched; PR assignee os-project-manager set at pr_create.",
      "tests": "Red first: domains/automation.ts + domains/actions.ts restored from base 05f7758f, run-door-input-shape.test.ts + field-error-code-catalog.test.ts: 78 failed / 59 passed (every refusal red, every preservation green). Ablations via scripts/ablation-replace.mjs on src (tests import src relatively, no dist leg), each anchor 1 to 0 and restored to the HEAD blob with git diff HEAD empty: action body check to undefined, 17 failed; action params check to undefined, 36 failed; trigger body check to undefined, 33 failed. Green at e321fc54: pnpm --filter @objectstack/runtime typecheck && test under the lock, VERDICT command-exit 0, 453 files, 7399 passed / 19 skipped. Live fresh showcase boot: action door params string/array/null/42 and body string/array/42 all 400 VALIDATION_FAILED; trigger door (both routes) body string/array/number/boolean 400 at (body); resume body string/array/number 400 with the unchanged sentence; controls dispatch; the runs listings show only the control runs (refused calls left no run row); MCP run_action with a string or array params is refused by the tool schema (-32602).",
      "gates": "node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack at e321fc54 vs merge base c8cb510a: 69 families, all 69 exit 0 (exit codes captured per command before any pipe); --ran: 69 derived, 69 run, 0 NOT-MEASURED, 0 UNRUN. eslint --no-inline-config packages/runtime exit 0. Full pnpm turbo run build 121/121 after the origin/main merge. On the first pass (pre-move head) check:route-envelope was red on the helper module under src/domains, so the module moved; check-plugin-teardown-shape --self-test (shallow clone, exit 3) and check:dual-build-cjs-loads (pre-build, exit 3) were green on the rerun. CI check-runs on #26034: in_progress at report time, not waited on.",
      "dogfood_battery": "e321fc54 · os-verify-lock VERDICT command-exit 1 · Test Files 1 failed / 295 passed / 3 skipped (299) · Tests 1 failed / 2522 passed / 18 skipped (2541) · failure: test/authz-probe-blind-spot.test.ts, 'packages/runtime/src/domains/i18n.ts — every positive control is still present in THAT file' (control handleI18nRequest expected 3, received 4). Not this diff: i18n.ts and the census file are byte-identical to origin/main (git diff origin/main HEAD empty for both), and origin/main's i18n.ts has 4 occurrences since 69fa23d6, so it is a red on main's full battery.",
      "mcp_calls": "0",
      "api_writes": "2 — relay pr_create (repository_dispatch fw-20261026T095033Z-127332, pr_create #26034); relay comment on #25976 (this report). git push is not a REST write.",
      "open_questions": [],
      "out_of_scope_findings": [
        "class: main-red (full battery) · reach: pnpm --filter @objectstack/dogfood test on a tree whose packages/runtime/src/domains/i18n.ts and packages/qa/dogfood/test/authz-probe-blind-spot.census.ts are byte-identical to origin/main c8cb510a reds authz-probe-blind-spot.test.ts with 'control handleI18nRequest moved in packages/runtime/src/domains/i18n.ts: expected 4 to be 3'; origin/main's i18n.ts carries 4 occurrences since 69fa23d6 (the translations ETag change) · dedupe words: authz-probe-blind-spot i18n control count, handleI18nRequest census 3 vs 4, dogfood main red i18n ETag",
        "carrier: none · noted, not filed — the MCP run_action door (action-execution.ts invokeBusinessAction) reads params with the same truthy-object guard, but the tool's input schema refuses a non-object params before it (measured -32602); PR Acceptance notes only"
      ]
    }

    Generated by Claude Code

  5. objectstack-fleet commented on Oct 26, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed

    PR #26034 merged at 2026-10-26T11:10Z by the merge queue as 3821ec8906 on main (Fixes #25976; ACCEPT 6413370555).

    Reading Probe Result
    Queue membership git ls-remote origin 'refs/heads/gh-readonly-queue/main/pr-26034-*' 0 refs
    origin/main by content git cat-file -e origin/main:packages/runtime/src/object-value-shape.ts present
    Ancestry git merge-base --is-ancestor 3821ec8906 origin/main holds

    State: this card closed by Fixes (completed); pm:dispatched removed.


    Generated by Claude Code

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

Metadata

Metadata

Labels

area:automationbugSomething isn't workingdomain:serverDomain lane — seat card indexed by label:pm:seatpriority:p2Medium: important, M3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions