Skip to content

Automation create_record under runAs:'system' inserts rows with owner_id/organization_id/created_by all NULL — records born untouchable even by admin #5494

Description

@yinlianghui

Part of objectstack-ai/hotcrm#700

Found during HotCRM's 17.0 GA acceptance sweep on @objectstack/* 17.0.0-rc.2, flow phase. Same root shape as the ctx.api action-body stamping gap HotCRM hit earlier (hotcrm#548), but a different writer: the automation engine's create_record node under runAs:'system'. Filed separately so the fix isn't assumed covered by whichever patch closes the action-path variant.

Reproduction (observed live, timestamps from the acceptance run's devserver2.log)

  1. 08:13:03 — manual trigger of a runAs:'system' scheduled sweep (contract_renewal) created a task and an opportunity via create_record nodes.
  2. Both rows: owner_id = NULL, organization_id = NULL, created_by = NULL (the app-level owner lookup gets a value; the platform columns do not).
  3. 08:19 — as admin: DELETE → 403 FORBIDDEN; repair PATCH {owner_id:…} → 403 as well.
  4. 08:20 — a demo-scaffolding flow's 10-minute claim pass stamped owner_id on the rows.
  5. After that: the same PATCH/DELETE → 200.

Step 4/5 is the tell: nothing about the caller changed between the 403 and the 200 — only the row's owner_id did.

Impact

Demo scaffolding is a crutch real installs don't have: every record a scheduled sweep creates is born admin-untouchable — renewal tasks/opportunities, stalled-deal tasks, snapshot rows. Nobody can edit, complete, reassign, or delete them without DB-level intervention.

organization_id = NULL additionally leaves such rows outside the org partition: unique indexes on (organization_id, …) don't bite across the NULL boundary and org-scoped queries may not see the rows (this produced a duplicate visible-number pair in hotcrm#698's evidence).

Expected

ADR-0118 (#4608) defines the non-user-actor contract: explicit isSystem, fail-closed, no NULL ambiguity. The engine knows the org and could stamp it; for ownership, stamp a system/service identity or the flow's declared operating identity — anything but NULL.

Refs (checked for duplicates): #4608 (the contract ADR, closed), #5378 (author-time validator vs system columns — different defect). Sibling app-side report: objectstack-ai/hotcrm#700.

Activity

  1. self-assigned this
    on Aug 7, 2026
  2. hotlong commented on Aug 7, 2026

    @hotlong
    Contributor

    认领(services 座位 PM,维护者 2026-08-07 02:4xZ 点名接手 target:v17 三单,优先序 #5149 > #5494 > #5148):

    • 会话:session_015a5qkLzpGXhLL2F5gvJ7dD
    • 分支:claude/issue-5494-runas-system-stamping

    范围:automation 引擎 create_record 在 runAs:'system' 下的三列染色(owner_id / organization_id / created_by),按 ADR-0118(#4608)非用户行为者契约收口:显式 isSystem、fail-closed、禁 NULL 歧义——引擎知道 org 即染 org;所有权染系统身份或流程声明的运行身份。验收含正文复现形状:sweep 产的行,admin 直接 PATCH/DELETE 应 200 而非 403。落点 packages/services/service-automation(属本座位)。


    Generated by Claude Code

  3. added a commit that references this issue on Sep 2, 2026
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