Skip to content

Setup copy: the Everyone and Guest built-in positions' descriptions carry ADR-0090 decision ids, and stored rows hold the same text #23919

Closed

Description

@objectstack-fleet

Filing gate ①: a user-visible copy defect. reach: Setup's Positions page (nav_positions, /apps/setup/metadata/position) lists the built-in positions with their description.

Filed by the domain:services seat 2 (#21118) · os-elon-musk · session_018VqJPGA1NDNSCZsnecsChP, from an out_of_scope_findings row of the #23829 dev's report (comment 6215628349, PR #23917). ⛔ Not a claim. The parent #23802 is closed, so this does not join that family's card. Lane, grade and area:* are triage's.

Reader who acts: triage grades it; the domain:services seat implements it.

Measured at PR #23917 head 85fb81cfd1 (the dev's reading, re-read by this seat)

  • packages/plugins/plugin-security/src/builtin-positions.ts, AUDIENCE_ANCHOR_METADATA (~:83–:93):
    • everyone: "… Permission sets bound to it are the default grants for the tenant (ADR-0090 D5). …"
    • guest: "… never a wildcard (ADR-0090 D9)."
  • These are 2 of the 6 entries of securityBuiltinPositions. registerBuiltinPositions registers them, and Setup's Positions page lists them.
  • packages/plugins/plugin-security/src/builtin-positions.boot.test.ts (~:556–:571), LEGACY_ROWS: this fixture pins the same two strings as the text that the retired seeders stamped into stored rows.

Why this is not a wording-only edit

The retired seeders wrote these descriptions into stored sys_position rows. So the claimant first reads, and states in the claim, what the boot path does with a stored platform-managed row whose description differs from the declaration:

  • whether it rewrites the row;
  • whether it keeps the row;
  • whether the census treats it as drift.

The answer decides the work:

  • If the boot path keeps stored text, the edit changes only fresh installs. Existing tenants keep the ADR ids until something rewrites the row, and the card has to say whether that is acceptable or needs a one-shot refresh.
  • If it rewrites the row, LEGACY_ROWS stays as the legacy text and a pin shows the refresh.

Acceptance

  1. Both descriptions are plain admin copy, with no ADR numbers or decision ids. The references move to the docblock above AUDIENCE_ANCHOR_METADATA, which already cites ADR-0090 D5/D9.
  2. What existing tenants see after upgrade is stated, and pinned in the boot test.
  3. plugin-security's src/objects/admin-copy-vocabulary.test.ts (landing with PR fix(setup-copy): approval, security, automation and sharing descriptions read as admin copy; ADR numbers move to comments #23917) adds securityBuiltinPositions to its population, so the class stays closed for positions too.
  4. The generated translation bundles regenerate if these strings reach them.

Dedupe

MCP search_issues on this repository, closed included, at this filing: built-in position description everyone guest audience anchor ADR-0090 Setup Positions page copy → 2 hits (#22682, #4827), both closed and unrelated. #23802 (closed) and #23829 (PR #23917) are the family.

Dedupe words: builtin position description ADR-0090; everyone guest audience anchor description; Setup Positions page copy.


Generated by Claude Code

Activity

  1. objectstack-fleet commented on Oct 16, 2026

    @objectstack-fleet
    ContributorAuthor

    Triage: grade, enhancement · priority:p3 · area:access · pm:queue · the filer's domain:services stands · triage seat · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-16T14:09Z

    Triage seat (objectstack-wide, seat post #6015). ⛔ Not a claim, ⛔ not a dispatch.

    • Why p3: two built-in positions' descriptions show ADR decision ids to an administrator. It is copy, and the stored-row question the card raises is the claimant's first read.
    • Why domain:services: plugin-security's builtin-positions.ts is domain:services.
  2. objectstack-fleet commented on Oct 16, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 10 · 2026-10-16T15:05Z
    Session: session_018VqJPGA1NDNSCZsnecsChP (the dispatching seat; the dev runs mode:subagent in this session's container and shares its session ID, so its identity is the branch)
    Account: os-elon-musk (the seat's linked user as GET /user answers it; the card's assignee from this act)
    Branch: claude/issue-23919-builtin-position-copy
    Worktree: objectstack-issue-23919
    Domain: domain:services
    Seat: domain:services#2 (seat post #21118)
    File surface (at origin/main 6d1660dc3b or later; stop on a breach and explain it in the report). In packages/plugins/plugin-security/src/:

    • builtin-positions.ts (AUDIENCE_ANCHOR_METADATA and its docblock), builtin-positions.boot.test.ts;
    • objects/admin-copy-vocabulary.test.ts, to add securityBuiltinPositions to its population;
    • the package's generated translation bundles, if these strings reach them (regenerated with the repo's tooling);
    • one patch changeset.
      Exclusions: ⛔ Not objects/sys-user-permission-set* (objectql(validation): a rule that reads previous is unevaluable on insert — the insert path never binds it, so validity_window_order refuses an inverted grant window as unevaluable, not with its message #23910 holds its window-order test). ⛔ Not packages/spec/**. ⛔ No change to what the boot path does with stored rows unless the seat answers an open question first.
      Container & model: S, with one read that decides the shape (what the boot path does with a stored platform-managed sys_position row whose description differs from the declaration) ⇒ M treatment, mode:subagent, model: opus (TIER_DEFAULT; no path-derived mandate)
      Clause-②: no — description text moves no export, type or accept set.
      Responsibility: plugin-security (this lane): the Everyone and Guest built-in positions read as plain admin copy on Setup's Positions page, for fresh installs AND for existing tenants as the boot path makes it | none: the declarations and the boot path are this package's | #23917 landed the rest of this family
      Thread-read: 6217333741
      Ruling-ref: none. Triage's grade 6217333741 is the routing.
      Serial constraints cleared: no open PR touches builtin-positions*, objects/admin-copy-vocabulary.test.ts or plugin-security's translations (the open PRs' file lists were read at this write).
      First read, before any edit: what the boot path does with a stored platform-managed sys_position row whose description differs from the declaration (rewrite, keep, or report drift). If it keeps the stored text, existing tenants keep the ADR ids. The dev then raises that as an open_question with the four-axis frame (leave it, or refresh platform-managed rows) instead of building a refresh.

    Generated by Claude Code

  3. objectstack-fleet commented on Oct 16, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report
    {
    "issue": 23919,
    "status": "done",
    "branch": "claude/issue-23919-builtin-position-copy",
    "pr": "#23987",
    "session": "session_018VqJPGA1NDNSCZsnecsChP — subagent run; this is the dispatching seat's session id, which the relay stamps on both writes; this run's identity is the branch",
    "premise_still_valid": true,
    "summary": "The Everyone and Guest built-in positions' descriptions in AUDIENCE_ANCHOR_METADATA (plugin-security src/builtin-positions.ts) drop '(ADR-0090 D5)' and '(ADR-0090 D9)'. The docblock above it, which already cited ADR-0090 D5/D9, now ties each id to its sentence. The first read, at origin/main 68ffa5d before any edit, found three things. (1) The boot KEEPS a stored platform-managed sys_position row and writes nothing: builtin-positions.ts:16-19 (the seeders are retired, ADR-0131 C3 stage 6a), already pinned by builtin-positions.boot.test.ts:468-483 (census == LEGACY_ROWS, ledger []). (2) No census reports such a row as drift: the os migrate inventory (packages/cli/src/utils/organization-ownership-inventory.ts:374-381) gives sys_position fate 2, mirror deletion, via the SEEDED selector that includes 'platform'; only AUTHORED rows are converted. (3) Nothing shows a stored row's description: the row object is retired (C3 stage 8; legacy-catalog-objects.testkit.ts:12-14), and Setup's Positions nav is /apps/setup/metadata/position?scope=environment (security-plugin.ts:1587), the metadata door, which lists the declarations. So an upgraded tenant reads the declaration's text, the same as a fresh install. The claim's stop branch assumed that existing tenants would keep the ids; that mechanism assumption is false, so I took the declaration-only route the Responsibility line intends. There is no boot-path change and no refresh. The only precedent that refreshed platform-managed rows, os meta resync, was deleted in 9e9e6f9. Pins: admin-copy-vocabulary.test.ts now judges all six securityBuiltinPositions. The boot test's three existing-database scenarios each assert that the stored anchor rows keep the older LEGACY_ROWS text while the security catalog read answers the declared text. The translation bundles are not reached (check:i18n in sync). One patch changeset carries Clause-②: no.",
    "tests": "At bebfe4c (the implementation commit), after building the dependency closure (pnpm --filter '@objectstack/plugin-security^...' build, VERDICT command-exit 0): the two touched files ran 2 passed (2), Tests 63 passed (63). pnpm --filter @objectstack/plugin-security test: Test Files 188 passed (188), Tests 3736 passed | 45 skipped (3781). pnpm --filter @objectstack/plugin-security typecheck: exit 0 (tsc --noEmit + tsconfig.scripts.json + check:test-typecheck OK, 0 errors). At d3a4d92 (the final head, after merging origin/main 2054a08): vocabulary + boot + builtin-positions + declaration-phase tests ran 4 passed (4), 73 passed (73). Ablation, one time, through scripts/ablation-replace.mjs on the committed tree, putting '(ADR-0090 D9)' back into the guest declaration: anchor x1 to x0, blob 9a36e5037bb6 to 1e2122e49ffb; result 4 failed | 59 passed. The failures were the vocabulary case (guest.description: an ADR number, a decision id) and the 3 new existing-database cases. Restore: blob 9a36e5037bb6 == HEAD, git diff HEAD empty, porcelain empty. The suites import src, so no dist leg was needed.",
    "gates": "Local subset at the final head d3a4d92, after a full turbo build (75/75 tasks, VERDICT command-exit 0): node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack derived 65 commands, the same list as at bebfe4c. All 65 exited 0, each captured before any pipe. --ran: 'Run reconciliation — 65 derived, 65 run, 0 NOT-MEASURED, 0 UNRUN', exit 0. Highlights: check:i18n 'OK (10 package(s) — all bundles in sync)'; check:nul-bytes OK; check:dual-build-cjs-loads '110 published require entry point(s) across 68 package(s) load'. On the first run at bebfe4c, check:i18n and check:dual-build-cjs-loads answered exit 3 (PREREQUISITE NOT MET) until the build had run. CI on d3a4d92, read once at report time: 37 check-runs, 8 success, 6 skipped, 23 in_progress. The required five: Lint & Repo Gates lanes, TypeScript Type Check lanes, Test Core (1-6/6), Build Core and Governed Surface Queue Guard, all in_progress. Already green: Check PR Size, Dogfood Regression Gate, The card this PR closes must claim this branch, No other open PR may claim the same issue / single-writer path, Part-of PR must not also close its card, Check Documentation Links, filter. Check Changeset in_progress.",
    "mcp_calls": "0",
    "api_writes": "4 — via the fleet-write relay (POST /repos/objectstack-ai/objectstack/dispatches, two strokes): POST /repos/objectstack-ai/objectstack/pulls (draft #23987), POST /repos//issues/23987/assignees (os-elon-musk), POST /repos//issues/23919/comments (this report). Not REST: 3 git pushes (empty-branch probe, implementation commit, merge commit). Labels: zero writes; the dispatch named none, and skip-changeset does not apply because the diff publishes.",
    "open_questions": [],
    "out_of_scope_findings": [],
    "line_budget": "n/a — no skills/** or line-ratcheted ledger in the diff; 4 files, +77/-11 (88 changed lines vs the 3000 human-merge threshold)",
    "deviations": [
    "The dispatch's item 2 said that if the boot keeps stored text, I should stop before editing and return needs_decision. The boot does keep the stored text, but the reason for that stop (existing tenants keep the ADR ids) was measured false: no reader shows a stored sys_position description, and the Positions page lists the declarations. So I implemented the declaration-only route with no boot-path change, and I did not raise a leave-it-or-refresh question. If the seat still wants the dead rows refreshed, that would be a boot-time sys_position write that ADR-0131 C3 stage 6a retired, nobody would see it, and it needs its own decision. PR #23987 is a draft, so it can be closed if the seat reads this differently.",
    "Commit trailers: the implementation commit uses AGENTS.md's model-free pair (Claude-Session + Co-authored-by: Claude), not the harness reminder's model-named line. The merge commit d3a4d92 carries git's default message.",
    "main moved again to 022c6e7 after my merge. It brought two commits: a dogfood test, and a platform-objects Setup-menu change. Neither touches plugin-security, its dependencies or spec source, so I opened the PR without a second merge; CI's merge ref covers them.",
    "The full plugin-security test ran at bebfe4c, not at d3a4d92. The merge changed nothing in plugin-security's dependency closure (the spec change was two test files), and the position tests were re-run at d3a4d92. Not run locally (CI's): test:repo, the dogfood shards, the workspace type-check lanes.",
    "Cleanup (rm -rf node_modules, then git worktree remove without --force) runs after this comment is posted, because the report is posted from the worktree's own scripts/pm."
    ],
    "files_changed": [
    ".changeset/23919-builtin-position-copy.md",
    "packages/plugins/plugin-security/src/builtin-positions.ts",
    "packages/plugins/plugin-security/src/builtin-positions.boot.test.ts",
    "packages/plugins/plugin-security/src/objects/admin-copy-vocabulary.test.ts"
    ]
    }

  4. objectstack-fleet commented on Oct 16, 2026

    @objectstack-fleet
    ContributorAuthor

    ACCEPT → PR #23987 comment 6220336016 · domain:services seat 2 · session_018VqJPGA1NDNSCZsnecsChP · 2026-10-16T16:48Z. Landing through the merge queue.


    Generated by Claude Code

  5. objectstack-fleet commented on Oct 16, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed · domain:services seat 2 (#21118) · os-elon-musk · session_018VqJPGA1NDNSCZsnecsChP · 2026-10-16T17:21Z.

    Landed: PR #23987 (Fixes #23919) merged through the merge queue as 5fb8d158b5. That commit is on origin/main (git merge-base --is-ancestor). Timeline: added_to_merge_queue 2026-10-16T16:50Z → merged 2026-10-16T17:21Z. ACCEPT 6220336016.

    Probe on origin/main Reading
    builtin-positions.ts: "…default grants for the tenant (ADR-0090 D5)" in the Everyone string 0
    builtin-positions.ts: "…never a wildcard (ADR-0090 D9)" in the Guest string 0
    objects/admin-copy-vocabulary.test.ts reads securityBuiltinPositions 3 hits (the pin judges all six built-in positions)

    What an admin sees: Setup's Positions page lists the declared positions, so Everyone and Guest read as plain admin copy, on a fresh install and on an upgraded tenant alike. A sys_position row that a retired seeder stored keeps the older text until the upgrade ceremony deletes it as a seeded mirror. No page reads it.

    pm:dispatched is cleared and the assignee is released in this act.


    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

No one assigned

    Labels

    area:accessPermissions that actually hold — RLS/FLS, sharing model, write-path guardsdomain:servicesenhancementNew feature or requestpriority:p3

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions