Skip to content

spec: the runAs describe still says a system flow keeps system privileges, but its writes to the four identity-assignment objects are now refused (#25251 PR2) #25554

Closed

Description

@objectstack-fleet

Filing gate ①: follow-up owed by landed work (PR1 of ruling 6354966423, letter B, on #25251, merged as #25483). The published FlowSchema.runAs describe now states a false rule. ⛔ Not a claim.

Reader who acts: domain:spec seat 1, in one PR. The same release as #25483's minor must carry it (ADR-0087, see the ACCEPT on #25483 and the Blocked-by on #25251).

The problem, in one sentence

An AI author reading runAs is told that a runAs: 'system' flow "keeps system privileges". Since #25483, the same flow's governed writes to sys_user_position, sys_user_permission_set, sys_invitation and sys_member are refused with PERMISSION_DENIED, so the published contract and the runtime disagree.

Reach

Public surface: the runAs describe ships in @objectstack/spec (JSON schema, generated reference docs, skills/** references). It is read by every author of a flow.

What PR2 carries (from the hand-off 6368756448 on the spec seat post, and ruling 6354966423)

  1. packages/spec/src/automation/flow.zod.ts, the runAs describe and its comment block. One sentence: a system run's governed writes (insert, update, delete, transfer, restore, purge) to those four objects are refused with PERMISSION_DENIED. The remedy is runAs: 'user' for grants, which the ADR-0090 D12 gate then judges, and the organization endpoints for invitations and memberships. Platform writers without a flow run are unchanged.
  2. The ADR-0087 D3 semantic entry for that change of meaning, as feat(plugin-security)!: a flow that runs as system writes no identity assignment #25483's changeset (Metadata-protocol: semantic) left it to PR2.
  3. ADR-0073: the sentence "runAs:'system' stays god-mode throughout" gets a dated amendment naming the four-object refusal. The contract review of feat(plugin-security)!: a flow that runs as system writes no identity assignment #25483 answered this as PR2's. If it is a governed (Tier H) path, it goes as a separate maintainer-merged PR and does not hold items 1 and 2.

Regenerate the derived reference pages with the repo's tooling. One changeset.

Duplicate search: repo:objectstack-ai/objectstack is:issue runAs describe 25251 → 0 hits.

Related: #25251 (closes when this lands), #25483, ADR-0073, ADR-0087, ADR-0090 D12.


Generated by Claude Code

Activity

  1. objectstack-fleet commented on Oct 24, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 2
    Session: session_013yig39ZouqWBxABRfM5FN4 (the card thread; seat session session_013odhA26dvzy7pQmevdTTvy posts this claim)
    Account: os-tesla
    Branch: claude/project-thread-7mlrrw
    Worktree: objectstack-issue-25554
    Domain: domain:spec
    Seat: domain:spec#1 (seat post #6017)
    File surface: packages/spec/src/automation/flow.zod.ts (the runAs describe and comment), the ADR-0087 D3 registration, docs/adr/0073-automation-execution-identity.md only if not governed, derived reference pages and ledgers, one changeset (stop on breach; explain in the report).
    Container & model: S, mode:thread, effort: high
    Clause-②: no (describe text and ADR registration only; no accept-set change)
    Metadata-protocol: semantic (records the change of meaning #25483 landed)
    Responsibility: n/a — follow-up owed by landed PR1 #25483
    Thread-read: none
    Serial constraints cleared: none touch these paths in flight. Must land before the next release cut, together with #25483 (ADR-0087).

    The platform lets the card thread push only its designated thread branch, so Branch: records that branch. Dispatch order: the project's shared folder, spec-seat-1/dispatch-25554.md. The seat runs a CONTRACT_REVIEW_TIER review before the queue.


    Generated by Claude Code

  2. objectstack-fleet commented on Oct 24, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
      "issue": 25554,
      "status": "done",
      "branch": "claude/project-thread-7mlrrw",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/25564",
      "head": "5a9bf414cf",
      "session": "session_013yig39ZouqWBxABRfM5FN4",
      "premise_still_valid": true,
      "summary": "The FlowSchema.runAs describe gains one sentence: a system run's governed writes (insert, update, delete, transfer, restore, purge) to sys_user_position, sys_user_permission_set, sys_invitation and sys_member are refused with PERMISSION_DENIED; declare user for grants (the ADR-0090 D12 gate judges the acting user) and use the organization endpoints for invitations and memberships. The comment block above runAs states the predicate #25483 enforces (isSystem AND flowRunId, ahead of the isSystem bypass, 403, nothing written; reads, other objects and flow-less platform writers unchanged). The ADR-0087 D3 semantic entry flow-run-as-system-identity-assignment-write-refused is added to protocol 18 (no D2 conversion). gen:docs regenerated two reference pages; gen:skill-refs and gen:skill-docs produced no diff. ADR-0073 is Tier H, so its amendment is drafted below and left out of the PR.",
      "tests": "At 5a9bf414cf: pnpm --filter @objectstack/spec build under os-verify-lock, VERDICT command-exit 0. pnpm --filter @objectstack/spec exec vitest run --maxWorkers=2 src/migrations src/automation/flow, VERDICT command-exit 0, Test Files 25 passed (25), Tests 1122 passed (1122). No ablation: no tested behaviour changed (describe text, comment, registry entry, generated docs).",
      "gates": "dispatch-gates --commands --repo objectstack-ai/objectstack at 5a9bf414cf derived 109 families; each run with exit code captured before any pipe. First pass: 102 exit 0, 7 exit 3 (PREREQUISITE NOT MET: shallow clone for check-plugin-teardown-shape --self-test; unbuilt formula/lint/client-react/objectql for check:doc-formula-expressions, check:doc-security-posture, check:skill-examples, check:docs-transcript-drift, check:lean-entry-closure, check:dual-build-cjs-loads). After git fetch --unshallow and a locked turbo build of lint..., client-react... and objectql (37/37 tasks), six re-ran exit 0. dispatch-gates --ran: 109 derived, 108 run, 1 NOT-MEASURED, 0 UNRUN. NOT MEASURED: check:dual-build-cjs-loads, reason: reads every workspace package's dist (hono, account, setup, studio, connectors...), a whole-workspace build that CI's Build Core owns. PR check-runs: in_progress at report time.",
      "line_budget": "99 changed lines (+92 / -7) over 5 files, under the 3000 human-merge threshold.",
      "files_changed": [
        ".changeset/25554-runas-identity-assignment-wording.md",
        "content/docs/references/api/automation-api.mdx",
        "content/docs/references/automation/flow.mdx",
        "packages/spec/src/automation/flow.zod.ts",
        "packages/spec/src/migrations/entries/semantic/18.flow-run-as-system-identity-assignment-write-refused.ts"
      ],
      "deviations": [
        "Changeset level minor, not the dispatch order's patch: Metadata-protocol: semantic requires at least one moved package at minor under ruling A (check-changeset-no-major.mjs header, 2026-10-21 on #25105). The Clause-② and Metadata-protocol lines are the claim's, verbatim.",
        "Dispatch item 3 (ADR-0073 amendment) left out: check-governed-merges --test answers GOVERNED, landing tier H, for docs/adr/0073-automation-execution-identity.md. Draft text in adr_0073_draft below, for the seat to route.",
        "The describe sentence does not carry the platform-writer clause (a flow author is never a flow-less platform writer); that clause is in the source comment block above runAs."
      ],
      "adr_0073_draft": "Replace line 155 of docs/adr/0073-automation-execution-identity.md, the bullet reading: runAs:'system' stays god-mode throughout. With: - runAs:'system' stays god-mode throughout, **except identity assignment (amended 2026-10-24, #25251 ruling 6354966423 letter B, landed in #25483 and #25564):** a governed write (insert, update, delete, transfer, restore, purge) to sys_user_position, sys_user_permission_set, sys_invitation or sys_member from a context that carries isSystem and a flowRunId is refused with PERMISSION_DENIED (403) ahead of the data middleware's system bypass. Position holdings and permission-set grants go through runAs:'user', which the ADR-0090 D12 gate judges as the acting user; invitations and memberships go through the organization endpoints. A system writer whose context carries no flow run is unchanged.",
      "dogfood_battery": "n/a — no ! in the PR title and no (narrowing) arm",
      "mcp_calls": "0 — no MCP GitHub tool used (card, comments and PR read through the public REST API)",
      "api_writes": "2 — POST /repos/objectstack-ai/objectstack/pulls (draft #25564, assignees os-tesla) via fleet-write relay run 40046903480; POST /repos/objectstack-ai/objectstack/issues/25554/comments (this os-dev-report) via post-stamped.mjs. git push of claude/project-thread-7mlrrw is not a REST write.",
      "open_questions": [],
      "out_of_scope_findings": []
    }

    Generated by Claude Code

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