Skip to content

fix(plugin-approvals): a new delegation starts with the Delegator set to you, and its help says why - #25420

Merged
objectstack-fleet[bot] merged 2 commits into
mainfrom
claude/issue-25342-delegator-prefill
Oct 23, 2026
Merged

objectstack-fleet[bot] merged 2 commits into
mainfrom
claude/issue-25342-delegator-prefill

Conversation

@objectstack-fleet

@objectstack-fleet objectstack-fleet Bot commented Oct 23, 2026 •

Copy link
Copy Markdown
Contributor

Requested by Sales · project thread

Fixes #25342

Clause-②: no
Metadata-protocol: none

What

Setup → Delegations (OOO): the Delegator of sys_approval_delegation only ever offers the signed-in user, because bindDelegationWriteGuard admits nobody else. The field still opened at "Select…", and a search for a colleague answered "No options found" with no reason.

Why this spelling

I checked how the platform defaults a person field to the current user, on origin/main 830a63a680:

  • packages/spec/src/data/field.zod.ts defaultValue says current_user is legal "on user or lookup with reference: 'sys_user' only". The spec's token table is defaultValueTokenIssue in packages/spec/src/data/default-value-shape.ts, and the constant is DEFAULT_VALUE_TOKEN_CURRENT_USER in default-value-tokens.ts.
  • The engine resolves it at insert time to the acting user's id: packages/objectql/src/engine.ts, the isCurrentUserDefaultToken branch of the field-default pass. With no authenticated user it leaves the field unset.
  • The one in-repo declaration is examples/app-showcase/src/data/objects/field-zoo.object.ts f_owner (Field.user({ defaultValue: 'current_user' })). No other platform object defaults a lookup to the current user, so this is the first such platform field. It uses the spelling the spec, the engine and the docs (content/docs/data-modeling/field-types.mdx) all name.

packages/spec is not edited.

Translations

  • en was regenerated with node scripts/check-i18n-bundles.mjs --write.
  • es-ES and ja-JP were byte copies of the old English help. They now carry translations, and the next extract dropped their two source-hashes entries.
  • zh-CN already had a translated help, so I updated it to the new meaning too. It has no hash entry, so nothing would have flagged it as stale.

Tests

packages/plugins/plugin-approvals/src/sys-approval-delegation-delegator-picker.test.ts keeps every existing pin. It gains one for the default: the declaration and the registered body carry DEFAULT_VALUE_TOKEN_CURRENT_USER, and a full FieldSchema.safeParse of the field is green, so the spec admits the token on this lookup.

  • pnpm --filter @objectstack/plugin-approvals test: Test Files 94 passed (94), Tests 1215 passed (1215).
  • pnpm --filter @objectstack/plugin-approvals typecheck: exit 0. check:test-typecheck reports OK.
  • Ablation: deleting defaultValue: 'current_user', (scripts/ablation-replace.mjs, anchor x1 -> x0) turned the new pin red (expected undefined to be 'current_user', 1 failed | 9 passed). The file was restored to its HEAD blob and git diff HEAD was empty. The test imports the object from src/, so no build was needed. My first attempt was a refused anchor miss, so nothing ran on it.
  • Derived gate families: run locally on this head. The PR's check-runs carry the full set.

Acceptance notes

  • The console's form prefill is NOT MEASURED. objectui answers 403 from this container, so I could not read how its create form treats a current_user default. The server side is pinned. If the console does not prefill from this token, that gap belongs to objectui and would hit the showcase f_owner field too. It is not a reason to change the spelling here.
  • Server-side writes behave as before. The engine default and the write guard's omitted-delegator stamp both name the acting user. A system write with no user still leaves the field unset, so required refuses it, and the existing pin holds that.

🤖 Generated with Claude Code

https://claude.ai/code/session_016g7nYP9wdNx1GDa5XDr7Uy

@github-actions github-actions Bot added size/s documentation Improvements or additions to documentation tests tooling Fix lands in tooling, not a product package — enters pm:queue only with Unblocks: or a named surface labels Oct 23, 2026
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 1 package(s): @objectstack/plugin-approvals, touching 4 documentable anchor(s).

2 hand-written doc(s) NAME something this change touched and may need an implementation-accuracy re-verification:

  • content/docs/automation/approvals.mdx (via sys_approval_delegation (symbol, a field of const object enObjects; a field of const object esESObjects; a field of const object jaJPObjects; a field of const object zhCNObjects))
  • content/docs/data-modeling/objects.mdx (via sys_approval_delegation (symbol, a field of const object enObjects; a field of const object esESObjects; a field of const object jaJPObjects; a field of const object zhCNObjects))

⛔ 1 release-owned page(s) also name something this change touched. These are read-only:

  • content/docs/releases/v16.mdx (via sys_approval_delegation (symbol, a field of const object enObjects; a field of const object esESObjects; a field of const object jaJPObjects; a field of const object zhCNObjects))

content/docs/releases/ is RELEASE-OWNED (AGENTS.md "Documentation Guardrails"): release
notes are written centrally at release time, and a code PR that edits them is the exact PR
that guardrail exists to stop. They are still audited — read-only. If one of them is actually
wrong, file an issue or open a dedicated docs-only PR; do not edit it here.

What this run could not see
  • 1 anchor(s) matched too much of the corpus to be a work list: current_user (literal, 35 pages)
  • the SDK route bridge reached 54 of 206 client-bound route-ledger rows — the other 152 have no registrar path: tail to select them, so pages documenting THEIR client methods cannot appear above, on this or any run. Of those 152: 0 are remediable by widening that discovery convention (an in-repo file declares the path; the convention did not scan it); 55 are structural — on a ledger where NOT ONE row is declared in-repo, so no discovery change reaches them at any price; 97 are undecided (no in-repo declaration, on a ledger that has other in-repo registrars — absence and an unreadable spelling are not distinguishable here). The rows themselves: node scripts/docs-audit/affected-docs.mjs --bridge-coverage
  • a page that states a rule by its inputs shares no identifier with the emitter that implements the rule, so an emitter-only diff cannot list it — not on this run and not on any run. Measured on fix(driver-sql): emit varchar(maxLength) for a text field a declared index keys on #11430: content/docs/protocol/objectql/types.mdx documents the text-family column mapping by the ObjectQL type names it maps FROM (text / textarea / html) while the diff changed createColumn; it went unlisted, and it was the page that diff falsified, in four places. No shared token exists to detect this on, so a rule your change carries has to be re-read by hand in the pages that restate it.
  • a key NAME is not a key, so the hand re-read the line above prescribes can land on the wrong schema. The same spelling is authorable on one governed type and a [REMOVED] tombstone on another for each of active, aria, joins, objects, template, tools and version (censused on [finding] tools is a key on BOTH AgentSchema (tombstoned, dead) and SkillSchema (live, cloud-attested), so a name-based search attributes skill examples to the agent key — it produced a false stop-the-line alarm on PR #19059 #19093 over the liveness ledger's governed types, top-level keys); nothing in a search result distinguishes the two, so a grep hit on a LIVE example reads as evidence about the DEAD key. Measured on fix(spec): the agent.tools liveness row says dead — it claimed live on a key the schema tombstoned #19059: content/docs/ai/agents.mdx was reported as contradicting the agent.tools tombstone over its tools: example at :161, which is inside the defineSkill({ block opened at :155 — the page was already correct. Settle ownership by PARSING the value against both schemas, never by the name: that literal PASSES SkillSchema, and as an AgentSchema it FAILS at tools with the tombstone prescription. ⛔ These names are not the whole class — a key retired through a .strict() guidance map leaves no tombstone in the walked shape and none of them here (tool.category, live as AIToolDefinition.category).

Coarse fallback — 6 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): node scripts/docs-audit/affected-docs.mjs --json f0fdd45bbc83f13d35af54f1ec903320340617c1 → packageMentionDocs.

Which tree this was computed on

This run read content/docs from eb119acb1597cd01eef3e947253426960140c412 — the merge of head 4194149960094594115e755890af323d69766d47 into base f0fdd45bbc83f13d35af54f1ec903320340617c1, which is what actions/checkout gives a pull_request run. Not the PR head.

A worktree cut from an older main holds a different content/docs, so re-deriving there can legitimately return a different list — that is a different tree, not a wrong row. To answer on the same tree:

# while this PR is open — GitHub drops the merge commit once it closes
git fetch origin eb119acb1597cd01eef3e947253426960140c412 && git checkout eb119acb1597cd01eef3e947253426960140c412
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin f0fdd45bbc83f13d35af54f1ec903320340617c1 4194149960094594115e755890af323d69766d47 && git checkout -B drift-repro f0fdd45bbc83f13d35af54f1ec903320340617c1 && git merge --no-ff 4194149960094594115e755890af323d69766d47

node scripts/docs-audit/affected-docs.mjs --json f0fdd45bbc83f13d35af54f1ec903320340617c1

⚠️ That checkout carried uncommitted changes, so the commit above does not fully identify what was read.

Advisory only, and a precision-first one (#9192): a page is listed because it names a
symbol, wire route or SDK method this diff touched — not because it mentions a changed
package. Each row says which anchor put it there, so a wrong row is reportable rather than
merely annoying. To re-verify, run the docs-accuracy-audit workflow scoped to these files:
node scripts/docs-audit/affected-docs.mjs f0fdd45bbc83f13d35af54f1ec903320340617c1 → pass the list as
args.docs, on the commit named under Which tree this was computed on.

@objectstack-fleet
objectstack-fleet Bot requested a review from os-sales October 23, 2026 13:13
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

席位核对 · ACCEPT · 2026-10-23T13:14Z

domain:services seat 1 (seat post #6021) · os-sales · session_016g7nYP9wdNx1GDa5XDr7Uy · card #25342 (S, in-seat subagent; os-dev-report on the card) · reviewed head 4194149960094594115e755890af323d69766d47

  • Diff, read file by file against the claim's surface: 9 files, +47 / −10.
    • delegator_id gains defaultValue: 'current_user', which is the spec's runtime token for a sys_user lookup (DEFAULT_VALUE_TOKENS, resolved at insert by objectql). The field's help now says why no one else can be chosen.
    • lookupFilters, the delegation write guard, organization_id and the approval-service filter are untouched.
    • The en bundle is regenerated. es-ES and ja-JP (byte copies of English until now) and zh-CN carry the translated help. The two stale source-hash entries are dropped.
    • Changeset 25342-delegator-prefill.md (patch).
  • Stop condition: not met. The spelling is the spec's own, and the showcase f_owner field declares the same token. packages/spec is not edited.
  • Pins (report): a new pin covers the declared and registered default, with a full FieldSchema.safeParse. The existing picker pins are kept. The ablation (default removed) turns the new pin red, and the restore is byte-identical to HEAD.
    • plugin-approvals 94 files / 1215 tests pass. Typecheck exits 0.
    • dispatch-gates --ran is 68 derived, 66 run, 2 NOT MEASURED and declared to CI.
  • CI on this head: 34 success and 7 expected skips, none failed or pending. Mergeable clean, and git merge-tree onto today's main is clean.
  • Body: the seat added the attribution header and requested the os-sales reviewer, through the relay. The closing footer is present.
  • Declarations: Clause-②: no, Metadata-protocol: none. The help text and the default are presentation, and the guard is unchanged. No contract-review record or dogfood battery is owed.
  • Out-of-scope finding, Acceptance notes: whether the objectui create form prefills a current_user default could not be read from this container. It is a read gap, not a repro, and is not filed. If it does not prefill, the insert still resolves the token server-side, so the row is right either way.
  • Commit trailers: model-free Co-authored-by: Claude + Claude-Session, as the repo's pre-push trailer check requires.
  • Landing: not governed (check-governed-merges --pr 25420: 57 lines). Ready + auto-merge through the relay. Fixes #25342 closes the card on merge.

Generated by Claude Code

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

Labels

documentation Improvements or additions to documentation size/s tests tooling Fix lands in tooling, not a product package — enters pm:queue only with Unblocks: or a named surface

Projects

None yet

2 participants