Skip to content

spec+server: an ownership queue primitive (queue entity, membership, claim) and declarative assignment rules, so an app routes ownerless records without app-level round-robin (maintainer ruling D6 = A) #25769

Open

Description

@objectstack-fleet

Ruled: 6457475657 · letter A (queues reserved key) · 2026-10-28T00:43Z

Filing-gate category: ③ maintainer-directed. Tesla ruled the whole-project assessment's D6 on 2026-10-25 09:23Z in the director thread, answering "A = queue/assignment rules are a real platform need, file the objectstack card, hotcrm deletes its STOPGAP after it lands; B = it is legitimate app logic": 「D4 · 固定发版日 没必要;其他同意 ,npm dist-tag 手工清理 应该立一张管理者维护的卡」 — "其他同意" read as A, the recommendation; the director thread said so back to Tesla at 09:25Z. ⛔ Not a claim; for triage to grade and route. New protocol surface: the contract shape is Tesla's to approve in the PR (Tier H through the ADR it adds).

Governing text: packages/spec/src/automation/approval.zod.ts on the deprecated queue approver type — "Re-admit only together with a real ownership-queue implementation (queue entity + membership + claim)"; packages/spec/src/security/sharing.zod.ts — "the runtime contract additionally reserves queue (no sys_queue yet) — it is deliberately NOT authorable until the implementation lands". hotcrm AGENTS.md rules 1–2 (platform gaps are filed upstream, never compensated in the app).

Who needs it today (the pull)

  • hotcrm src/service/objects/_case-assignment.ts (587 lines) opens with "⛔ This module is a STOPGAP. It is the code to delete": a web-to-case submission has its owner_id stripped and "has nowhere to sit", so the app substitutes a least-loaded round-robin over a position pool, and has to route around the ownership-transfer gate to do it. lead_auto_assign in src/sales/objects/lead.hook.ts does the same for inbound leads (src/sales/flows/lead-assignment.flow.ts).
  • The reference app is the corpus AI copies most; today it teaches "write a hook that counts rows to pick an owner" while its own rules say never compensate. Lead and case routing is a standard need of any CRM-shaped app built on the platform.

What lands (one PR, spec key with its first reader — ruling D5)

  • spec: the queue entity, its membership (users / positions / teams, using existing recipient kinds), and a declarative assignment rule (criteria → queue or user, with round-robin / least-loaded as named strategies). Re-admit the deprecated queue approver type and the reserved queue sharing recipient once they are enforced.
  • server: the system object(s), the claim operation (an agent takes a record from a queue; ownership transfer through the existing gate, not around it), the assignment-rule evaluation on insert, and the approvals / sharing branches the two deprecated members were waiting for.
  • A shape proposal comes first in the PR's 维护者速读 (Chinese, business view) with the ADR; the dev reports a fork if the shape needs a choice the governing text above does not settle.
  • Downstream: the hotcrm card that deletes the STOPGAP is filed alongside and blocked on this one; it unblocks when a published @objectstack/* release carries this, not at merge.

Readers: triage (route; likely domain:spec seam with server), then the claiming seat. Effort guess L, cross-package (spec, objectql/plugin-security/plugin-sharing/plugin-approvals): the risk / effort floor applies, which Tesla's ruling covers for direction; shape and naming stay with the PR review.

Duplicate check: semantic searches "queue assignment rule primitive round robin owner assignment lead case" (objectstack, 0 hits) and "case assignment STOPGAP sys_queue lead auto assign" (hotcrm, 1 closed unrelated: #507). No duplicate.

Evidence: https://claude.ai/artifact/8qxoYjsE4jQC4DJBCF3wm5#D6


Generated by Claude Code

Activity

  1. objectstack-fleet commented on Oct 26, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 1 · 2026-10-26T12:08Z
    Session: session_01HbmCEPMBmMLU3VZCEzfec7 (seat 4; the card thread is session_01GTntg542RUmmRRbMY6wMZD, which writes no claim of its own)
    Account: zhuangjianguo
    Branch: claude/project-thread-g33c7k (the platform assigns the card thread's branch, and the thread can push only that branch. Written as measured, instead of claude/issue-25769-<slug>.)
    Worktree: objectstack-issue-25769
    Domain: domain:spec
    Seat: domain:spec#4 (seat post #18917; 由 zhuangjianguo 账户的项目负责)
    File surface: phase 2 of ADR-0142, ONE spec + server PR. Spec: packages/spec/src/automation/approval.zod.ts, packages/spec/src/security/sharing.zod.ts, a queue metadata type and its contract under packages/spec/src/**, the liveness rows and the generated references. Server: packages/plugins/plugin-sharing, packages/plugins/plugin-approvals, and the transfer-gate site in packages/objectql / packages/plugins/plugin-security. Plus tests and one changeset. If measurement puts the producer elsewhere, fix it there and say so. Stop on a breach and explain it in the report.
    Container & model: L, mode:thread, model: TIER_DEFAULT — dispatch-gates --tier: no path-derived mandate, effort: xhigh (p1)
    Clause-②: yes
    Metadata-protocol: added
    Responsibility: n/a — not a defect card
    Thread-read: 6411228108
    Premise: holds (at main 0a694821: the queue approver type is still deprecated in approval.zod.ts, the queue sharing recipient is still reserved, and no sys_queue object exists. ADR-0142 is Accepted, merged as 38050ced7b.)
    Ruling-ref: Tesla D6 = A (card body); ADR-0142 merged by os-zhuang; phase-2 carry 6409493120 (the ownership-queue service takes a name other than queue, and the Q17 boot refusal tests that name)
    Serial constraints cleared: seat 2 PR #26010 (#25866, plugin-security field permissions) is open; the thread merges main after it lands if it touches plugin-security. No other in-flight claim names these files.
    Resume-from: none (phase 1 branch claude/project-thread-eypatm merged; phase 2 starts from main, per Release 6411228108)

  2. objectstack-fleet commented on Oct 26, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
      "issue": 25769,
      "status": "done",
      "phase": "2 of 2 (spec + server, ADR-0142 Execution plan item 1); the card stays open: Part of, not a closing keyword",
      "branch": "claude/project-thread-g33c7k",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/26337",
      "pr_state": "draft, Tier H (over 3000 changed lines, touches skills/**); requested reviewers hotlong, os-zhuang (set by the relay's governed-review follow-up); assignee zhuangjianguo; label size/xl (auto). Body written once by the relay, read back identical (12021 bytes sent, 12021 stored) and read again in full through pull_request_read.",
      "head": "578e7a417f7394c57f1242b72d5a50032b1d1d0b",
      "session": "session_01GTntg542RUmmRRbMY6wMZD",
      "premise_still_valid": true,
      "summary": "Lands ADR-0142 phase 2 in one PR. Spec: the queue and assignment_rule metadata types, the queues and assignmentRules stack keys, the IOwnershipQueueService contract under the service name ownership-queue (not queue, per carry 6409493120), queue in ShareRecipientType and the injected system columns, the queue approver type re-admitted, QUEUE_NOT_FOUND in the ledger. Server: sys_queue, sys_queue_member, sys_assignment_cursor and the ownership-queue service in plugin-sharing with the sitting-record access path (read and edit, never delete) and the queue recipient; the queue column, registration refusal, by-id write precondition (409 CONCURRENT_UPDATE), assignment rules at insert and the kernel:ready boot refusal in objectql; claim, release and move admissions plus explain reasons in plugin-security; queue approvers in plugin-approvals; two lint rules, the activation door and the dogfood rows. Not carried: the queues RLS membership key (open question, needs a decision).",
      "tests": "All at head 578e7a417, each under scripts/pm/os-verify-lock.sh, VERDICT command-exit 0: objectql vitest 474 files / 8820 tests passed; plugin-security 228 files, 4964 passed, 45 skipped (pre-existing, none added); plugin-sharing 57 / 1271; plugin-approvals 98 / 1280; platform-objects 96 / 1361; lint 166 / 7393; runtime src/domains/catalog-activation-door.test.ts + src/route-ledger.conformance.test.ts 2 / 75; dogfood test/authz-conformance.test.ts 61; ui app-shell approverIdentity + FlowReferenceField.lookup 2 / 34; spec: the 10 touched test files plus src/security, src/automation/assignment-rule, src/stack, src/data/filter.test.ts 54 / 1955, and src/type-alias-convention.pin.test.ts 3 / 3. Full spec suite not run locally (over 560s on this box); CI runs it. Ablation, one behaviour the diff changed under an existing pin (the queue sharing recipient used to expand to nobody): node scripts/ablation-replace.mjs on plugin-sharing/src/sharing-rule-service.ts, anchor `return queues.expandMembers(...)` x1 to x0, replacement x0 to x1, blob 23bbe5b4c390 to 6285ab550023; src/queue-recipient.test.ts went red as predicted (2 failed, 2 passed of 4: 'grants each member the expander returns', 'a member who left loses the grant'); restore verified blob == HEAD and git diff HEAD empty; rerun 4 / 4 passed. The suite imports the service from src through a relative path, so no dist leg applies.",
      "gates": "Local: node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack at head 578e7a417 (merge base 5cb1c1a68, 168 paths) derived 163 commands, identical to the set at the previous head; all 163 run with each exit code captured before any pipe, every one 0 (check:type-check-debt under os-verify-lock.sh, closure build nested, re-measured 1 ledger entry, 26 raw tsc errors, none above its number). dispatch-gates --ran: 163 derived, 163 run, 0 NOT-MEASURED, 0 UNRUN. Timeouts raised to 590s for check-comment-mask-corpus, check:query-options-erasure and check:pm-dispatch-gates (they take about 4.5, 7 and 9 minutes on this box). CI at report time (head 578e7a417): success: Part-of PR must not also close its card, The card this PR closes must claim this branch, No other open PR may claim the same issue, No other open PR may claim the same single-writer path, Check PR Size, Check Documentation Links, filter; in_progress: Build Core, Build Docs, Build UI Deps, Test Core 1-8 of 8, Dogfood Regression Gate, Type Check (workspace, source gates, consumer gates, debt ledger), Lint (ESLint, repo and tooling gates, CI release and engine gates, docs and code guards, PM dispatch-gates, scoped tooling self-tests, scoped slot lookup and corpus, scoped query-options erasure), Governed Surface Queue Guard, Check Changeset, Spec property liveness, Flag docs affected by code changes, Auto Label; skipped by path selection: Temporal Conformance, Dogfood Verify CLI, dogfood shards, 18.x upgrade harness, Packed-tarball smoke. Not waited on, per os-dev.",
      "dogfood_battery": "n/a: no ! in the PR title and Clause-② carries no (narrowing) arm",
      "line_budget": "6610 changed lines (+6230 / -380, 168 files) against the 3000-line human-merge threshold: over, so Tier H and a governed approver. skills/**: skills/objectstack-platform/SKILL.md 488 to 488 lines, 5824 to 5826 tokens (ceiling 5828); whole bundle, 11 SKILL.md, 4525 to 4525 lines, 54450 to 54452 tokens. The two added keys are paid by deleting two ADR citations in the same file, no re-wrap.",
      "files_changed": [
        "168 files; the PR's Files tab is the list. By area:",
        "packages/spec: 63 (src 37, generated api-surface, export-origins, authorable-surface, declaration-map, json-schema.manifest, liveness ledgers and llms.txt 26), including new src/security/queue.zod.ts, src/automation/assignment-rule.zod.ts, src/contracts/ownership-queue-service.ts, liveness/queue.json, liveness/assignment_rule.json",
        "packages/plugins/plugin-sharing: 26, including new ownership-queue-service.ts, queue-hooks.ts, objects/sys-queue.object.ts, objects/sys-queue-member.object.ts, objects/sys-assignment-cursor.object.ts and their tests",
        "packages/plugins/plugin-security: 11, including new ownership-queue-gate.ts and its test",
        "packages/objectql: 10, including new assignment-rules.ts, concurrent-update-error.ts, ownership-queue.test.ts",
        "packages/plugins/plugin-approvals: 5; packages/lint: 10 (new validate-assignment-rules.ts and test); packages/runtime: 4; packages/platform-objects: 7; packages/metadata: 1; packages/metadata-core: 2; packages/qa/dogfood: 1",
        "ui/packages/app-shell: 4; skills/objectstack-platform/SKILL.md: 1",
        "content/docs: 24 (new references/security/queue.mdx and references/automation/assignment-rule.mdx, regenerated references, approvals.mdx, six prose counts); docs/audits: 3; docs/qa/platform-checklist/coverage.json: 1; examples/app-showcase/src/coverage.ts: 1",
        "scripts: platform-object-tenancy-census.json, check-stack-collection-maps.mjs, engine-double-contract.pinned.json; .changeset/25769-ownership-queue.md"
      ],
      "mcp_calls": "9, all GitHub reads: issue_read get #25769 (x2), issue_read get_comments #25769 (x4, the last one reading this report back), pull_request_read get_files #26010 (serial-constraint check), pull_request_read get #26337 (full body read-back), pull_request_read get_check_runs #26337. No write tool.",
      "api_writes": "2 relay dispatches (POST /repos/objectstack-ai/objectstack/dispatches, executed by fleet-write as objectstack-fleet[bot]): pr_create #26337 (POST /pulls draft, then POST /issues/26337/assignees; the governed follow-up requested hotlong and os-zhuang; run 40407067455), and this report comment through scripts/pm/post-stamped.mjs. Plus 4 git pushes to claude/project-thread-g33c7k (not REST). No label write: none was named and skip-changeset does not apply (the PR carries a changeset).",
      "open_questions": [
        {
          "question": "The queues RLS membership key. ADR-0142 Execution plan item 1 lists 'the queue service and its queues membership-resolver key'. The contract has one IRlsMembershipResolver slot, which an app's own resolver also fills, and the producer screens RESERVED_RLS_MEMBERSHIP_KEYS out of any resolver's answer. plugin-sharing therefore cannot supply queues without displacing an app's resolver or being screened out. This PR does not implement it; D3's access path does not need it (it goes through the plugin-sharing owner match).",
          "needs_decision": true,
          "options": [
            "A: reserve queues in RESERVED_RLS_MEMBERSHIP_KEYS and have plugin-security resolve it from the ownership-queue service, as the kernel resolves positions, in a follow-up on this card",
            "B: plugin-sharing registers its own IRlsMembershipResolver that supplies queues, displacing (or being displaced by) an app's resolver",
            "C: drop the key from the plan: RLS authors reach queue membership only through the sharing path"
          ],
          "four_axis": {
            "实际业务需求": "No consumer reads current_user.queues from an RLS policy today. HotCRM's D8 mapping parks and claims through the sharing owner match, which this PR ships. The pull for the key is a future app that writes an RLS predicate over queue membership.",
            "项目长远合理性": "A gives the key one kernel-side producer, the same shape as positions and org_user_ids; B makes the key's value depend on which resolver won the single slot; C leaves a gap the ADR named.",
            "防 AI 写错": "Under B an AI-authored app resolver can silently replace or clobber queue membership; under A the reserved-key screen fails closed, so a resolver that tries to supply queues is ignored, and the compiler refuses a membership bag that names it.",
            "创业阶段不扩散需求": "With no consumer today, A belongs in a small follow-up on this card, not in this already Tier H PR; C is acceptable if the maintainer prefers to wait for the first pull.",
            "spec 声明优先于实现与文档面": "The accepted ADR (the spec-level declaration) names the key and the implementation lacks it, so either the follow-up lands it (A) or the maintainer amends the plan (C). B contradicts the reserved-key contract."
          },
          "recommendation": "A, as a follow-up on this card, because it is the only option that keeps one producer for the key and fails closed against an app resolver, and nothing consumes it before then."
        }
      ],
      "deviations": [
        "File surface: the claim names spec, plugin-sharing, plugin-approvals and the gate site in objectql / plugin-security. Measurement also put edits in packages/lint, packages/runtime, packages/qa/dogfood (Execution plan item 1 names lint and dogfood), packages/metadata (artifact door maps queues and assignmentRules), packages/metadata-core, packages/platform-objects (labels in zh-CN, ja-JP, es-ES), ui/packages/app-shell (flow designer warning), skills/objectstack-platform/SKILL.md (check:skill-top-level-keys), scripts ledgers, examples/app-showcase coverage, docs/qa coverage and content/docs counts. Each is named in the PR body; the claim comment is the seat's to amend.",
        "Explain kinds are snake_case (queue_membership, queue_claim) where the ADR writes them hyphenated, matching every other ExplainRuleKind member.",
        "The injected queue column is declared hidden (QUEUE_FIELD_DEF). sys_queue_member.queue is a text column holding the queue name, not a lookup, because an organization staffs a declared queue, which has no sys_queue row, under its name.",
        "IOwnershipQueueService.expandMembers takes a purpose option, not in the ADR: access (the default) drops the holders of a position the activation ledger switches off, addressing (the approver slate) keeps them, following the maintainer ruling of 2026-08-15 that access-conferring paths filter deactivated positions and addressing paths do not.",
        "The registration refusal for a declared queue field applies to the base registration layer only.",
        "Declared assignment rules are validated at load time by lint only (the two new advisory rules, CLI only); the runtime logs an unresolved target once and leaves the row ownerless. declaredQueueNamed reads the registry, not the activation ledger.",
        "Round-robin cursor: a driver with no updateMany advances it unconditionally, logged once (merge question 7). A cursor that keeps losing races past CURSOR_RETRIES parks the row in the queue with a warning; this second fallback is not in the record.",
        "checkEdit carries a cross-organization guard on the sitting-record arm.",
        "An organization queue whose name clashes with a declared queue is refused with field code invalid_value: FieldErrorCode is a closed catalog with no duplicate member.",
        "Gate readings, each with a case in ownership-queue-gate.test.ts: an echo of the stored queue is not a move; a claim on a record with no queue is admitted when sharing positively admits it; clearing owner_id with no home queue is a disown and needs the grant; a member who supplies an empty owner beside a queue on insert is still stamped owner (merge question 13); a predicate update writing queue fails closed without the grant.",
        "The approvals empty-queue warning is unit-tested but not ledger-tested.",
        "New waivers: docs/qa/platform-checklist/coverage.json (queue, assignment_rule) and examples/app-showcase KIND_COVERAGE (queue, assignment_rule), each naming the HotCRM adoption phase as what retires it.",
        "The Console title derivation and the two-source queue picker are left to the objectui lane (Execution plan item 3); the spec carries the binding (APPROVER_VALUE_BINDINGS.queue reads both sources).",
        "The PR body's 维护者速读 section is in Chinese as os-dev requires for a governed-surface PR, while AGENTS.md asks for English GitHub text; both rules are followed, each in its own section.",
        "The PR body's first line is the harness attribution comment, kept verbatim as the coordinator required (os-dev's exception); Part of #25769 follows the Requested-by line.",
        "Two merges of origin/main, both on conflict: defd4522d (echo-decision count, explain-access imports, dropped-refinements baseline) and 578e7a417 (type-alias pin count 790 + 4 = 794 against #25808, regenerated references). main has moved since (495fa07c2) with no conflict, so no third merge.",
        "The full spec suite was narrowed locally to the touched files plus src/security, src/automation/assignment-rule, src/stack and src/data/filter.test.ts; CI runs the rest.",
        "Gate timeouts were raised for three slow gates (590s) after a first pass timed out at 290s; each then passed. No gate was skipped or narrowed."
      ],
      "out_of_scope_findings": [
        "carrier: this PR · the phase-1 report's stale header in plugin-sharing/src/access-level.ts (recipient_type queue 'was removed') is corrected here",
        "carrier: none · none new"
      ]
    }

    Generated by Claude Code

  3. objectstack-fleet commented on Oct 27, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
      "issue": 25769,
      "status": "done",
      "round": "patch round on PR #26337 (drive to green), not a rework",
      "branch": "claude/project-thread-g33c7k",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/26337",
      "head": "e45133760b7b95682a42b174a193d627ed5f996b",
      "session": "session_01GTntg542RUmmRRbMY6wMZD",
      "check_runs": "At head e45133760, all 63 check runs have completed: 58 success, 5 skipped by path selection (Dogfood Regression Gate shards, Dogfood Verify CLI, Temporal Conformance, Packed-tarball smoke, 18.x upgrade harness), 0 failed. The aggregates Test Core and TypeScript Type Check are green. Type Check · workspace passed at this head, so no plugin-hono-server OOM (#26288) is outstanding.",
      "narrowing": "Yes. registerObject now refuses a declared field named queue on an object whose records have a user owner (ownership user, the default), with 422 INVALID_METADATA (ObjectQueueColumnRefusedError). That body parsed and registered before this PR. The kernel:ready boot refusal is not a narrowing: it refuses only a stack that declares the new queues or assignmentRules keys with no ownership-queue service registered, and no such stack parsed before. The changeset (commit 6f9821785, title feat(spec)!) carries Clause-②: yes (narrowing) and Metadata-protocol: narrowed, and adds the ADR-0087 D3 entry object-queue-field-reserved (packages/spec/src/migrations/entries/semantic/18.object-queue-field-reserved.ts). The PR body still reads Clause-②: yes and Metadata-protocol: added, and the PR title has no !. Both are the seat's to patch.",
      "fixes_this_round": [
        "9bc508a8a plugin-sharing: the shadowed-queue report declares a required warn channel (check:optional-error-sink)",
        "6f9821785 spec: the narrowing declaration and the D3 migration entry",
        "e0cfccda8 merge of origin/main a8e7393dd for a main-caused red: main moved the error-code ledger, so the merge ref's generated ErrorCode counts were stale; regenerated",
        "4028072da cli: ADR-0131 D10 organization-ownership inventory rows for sys_queue, sys_queue_member and sys_assignment_cursor",
        "0f2b6ac15 platform-objects: the Queues and Queue Members nav labels in en, zh-CN, ja-JP and es-ES (check:app-nav-i18n)",
        "2448c0035 test pins: the injected queue column and the two code-only types (metadata-protocol, rest, cli schema gate, UI ListView fixture, app-shell inspector string, objectql typing)",
        "9ada3a920 driver-sql: the sort-anchor premise pin admits the text-typed queue anchor (Test Core 5/8)",
        "564ef7a63 objectql: two fail-path tests (a criteria that cannot be evaluated does not match and warns once; a load the compiler cannot lower parks the row and never counts every row), and a comment that claimed an authoring gate that does not exist",
        "e45133760 dogfood: expression-conformance ledger rows assignment-load (compile, fail-closed) and cel-assignment-criteria (interpret, fail-soft-log); the federated anchor provenance pin counts queue among the 8 injected, unprovisioned anchors"
      ],
      "dogfood_battery": "Full battery at head e45133760: the closure build (pnpm --filter '@objectstack/dogfood^...' build, 7m29s), then pnpm --filter @objectstack/dogfood test under os-verify-lock.sh, no OS_TEST_SHARD, no path, clean tree. 300 files: 297 passed, 3 skipped, 0 failed. 2548 tests: 2530 passed, 18 skipped, 0 failed. The lock was held 1311s. The first full run, at 9ada3a920, had 2 red files: test/expression-conformance.test.ts (no ledger rows for AssignmentRuleEntrySchema.criteria and .load) and test/federated-anchor-provenance.dogfood.test.ts (8 unprovisioned anchors, pin said 7). Those two are why the seat dequeued the PR (comment 6430742545). Neither PR CI nor the merge group runs the dogfood shards.",
      "gates": "node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack at head e45133760 derived 168 commands (one more than at 2448c0035: check:driver-conformance). All 168 run at that head, after the battery, each exit code captured before any pipe, every one 0. check:type-check-debt ran under os-verify-lock.sh. dispatch-gates --ran: 168 derived, 168 run, 0 NOT-MEASURED, 0 UNRUN.",
      "tests": "At head e45133760: objectql src/ownership-queue.test.ts 22 / 22; dogfood test/expression-conformance.test.ts plus test/federated-anchor-provenance.dogfood.test.ts 14 / 14 (and the full battery above). For Test Core 5/8 at 2448c0035, the shard's package set was computed locally (select-shard-packages.sh plus partition-test-shards.mjs) and run: driver-sql was the only red; the other packages passed, including plugin-auth 198 files / 3780 tests.",
      "adr_open_items_sentence": "Kept out of this PR, as docs/adr/** is governed. Text for the director seat or the maintainer to lift verbatim into ADR-0142 Open items: 'Whether the queue column is injected on every ownership: user object (D3 as accepted) or moves to a per-object opt-in was put to the maintainer in objectstack#26359, who confirmed D3 as accepted (ruling A, https://github.com/objectstack-ai/objectstack/issues/26359#issuecomment-6429748166).' The ruling id is taken from the director seat's pointer, comment 6429770469 on this PR.",
      "line_budget": "186 files, +6406 / -406 against main after this round's fixes. Still Tier H.",
      "mcp_calls": "GitHub MCP reads only: pull_request_read (check runs, get, reviews, comments), actions_list (workflow runs and jobs), actions_get, get_check_run, get_job_logs. They were not counted exactly across a context reset. No MCP write tool was used.",
      "api_writes": "1 relay dispatch: this comment, through scripts/pm/post-stamped.mjs. Git pushes to claude/project-thread-g33c7k landed heads 2448c0035, 9ada3a920 and e45133760 in this round, along with the earlier pushes of 9bc508a8a through 0f2b6ac15. Six pushes were refused with GH006 while the PR sat in the merge queue (00:27Z to 00:43Z), and one push landed after the user removed it from the queue. The dequeue, the draft flip and any re-arm are the seat's and the user's strokes, not mine.",
      "open_questions": "Unchanged from the first report: the queues RLS membership key (recommendation A, a follow-up on this card). Body keeps Part of #25769.",
      "next": "Seat: patch the PR body's declaration lines to Clause-②: yes (narrowing) and Metadata-protocol: narrowed (and the title's !, if the seat agrees), refresh the body's test section (it still says no dogfood battery), amend the claim, run the CONTRACT_REVIEW_TIER review on this head, flip ready and re-arm auto-merge."
    }

    Generated by Claude Code

  4. objectstack-fleet commented on Oct 27, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim amendment — seat domain:spec#4, session session_01HbmCEPMBmMLU3VZCEzfec7, 2026-10-27T01:53Z.

    PR #26337 measured a narrowing, so the seat takes the changeset's lines in place of claim 6415635954's:

    Clause-②: yes (narrowing)
    Metadata-protocol: narrowed

    File surface, widened as the PR body names it: packages/lint, packages/runtime, packages/qa/dogfood, packages/metadata, packages/metadata-core, packages/platform-objects, ui/packages/app-shell, skills/objectstack-platform/SKILL.md, the gate ledgers, examples/app-showcase coverage, docs/qa coverage and the content/docs counts.

    Landing: the PR is Tier H. os-zhuang APPROVED it on 2448c003, and it was armed once. The queue took it at 9ada3a920. The seat pulled it back to draft (6430742545) because the dogfood battery had 2 red files. The landing head is e45133760: CI green and the full battery green. The queues RLS membership key is not in this PR. It waits on the user's decision (seat recommends A, as a follow-up on this card), so the PR stays Part of #25769.

  5. objectstack-fleet commented on Oct 27, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
      "issue": 25769,
      "status": "done",
      "round": "re-review round after contract review 6430868091 (VERDICT FAIL at 9ada3a920), on the seat's option B",
      "branch": "claude/project-thread-g33c7k",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/26337",
      "head": "290a435afcbe1127dda5d09d7d0330d8e7522429",
      "session": "session_01GTntg542RUmmRRbMY6wMZD",
      "check_runs": "At head 290a435af, all 64 check runs have completed: 59 success, 5 skipped by path selection (Dogfood Regression Gate shards, Dogfood Verify CLI, Temporal Conformance, Packed-tarball smoke, 18.x upgrade harness), 0 failed. The aggregates Test Core and TypeScript Type Check are green. mergeable_state is blocked (review), not dirty. A merge-tree of this head against main 68901b038 is clean.",
      "review_findings": {
        "①-1": "Fixed in 45558e255. foldExtendersOntoDefinition (packages/objectql/src/registry.ts) now governs queue the way it already governs audit fields. When the base definition resolves the injected queue column (ownership user), each extend contribution has its own queue field dropped before the merge (withoutExtensionQueueField). The platform column stands, and one warning per object and package names the extension. This holds in either registration order, because the fold runs at read time over both layers. Test: packages/objectql/src/ownership-queue.test.ts, D3 describe, 'an extension's own queue never replaces the injected column, in either registration order, and is named once'. It covers both orders, checks that the extension's other fields are kept and that the warning fires once per registry, and checks that an ownership org object keeps the extension's queue. Ablation: with the fold line voided, the test is red. The D3 migration entry 18.object-queue-field-reserved (surface, acceptance criteria, proof) and the changeset's BREAKING paragraph now say that an extension's queue is ignored with a warning, not refused.",
        "②-1": "Covered by the seat's patch, not by a commit. The PR body carries Clause-②: yes (narrowing) and Metadata-protocol: narrowed, the title is feat!, and the claim was amended in 6431791644. Two body items are still stale and are the seat's to patch: the Tests and gates section (measured at 578e7a41, it still says no dogfood battery) and the line 'Two merges of main'. Replacement text is in landing_head_note. Main's b33dd25b2 (#26381), which is in this head, also owes the body a Skills-docs line; mine is in skills_docs.",
        "③-1": "Kept out of this PR on the seat's ruling, because docs/adr/** is governed. The sentence for the director seat or the maintainer to lift into ADR-0142 Open items is unchanged, in adr_open_items_sentence.",
        "readings": "The @objectstack/cli reading is answered: 45558e255 adds '@objectstack/cli': minor to the changeset, with a bullet for the three ADR-0131 D10 inventory rows. The precondition reading stands as read. The claim's by-id precondition, owner_id null, is pinned in packages/objectql/src/ownership-queue.test.ts against a test-double driver that honours writePrecondition, and in plugin-security's ownership-queue-gate.test.ts. No real-driver suite pins how a driver lowers a null equality inside a write precondition. That pin is a follow-up candidate for the seat to file; it is not in this PR."
      },
      "fixes_this_round": [
        "45558e255 objectql: an extension's own queue field never replaces the injected column (finding ①-1), with its test, the migration entry and the changeset (cli added)",
        "a554823c6 merge of origin/main for a conflict: the type-alias Iso pins (main's seed-file pin keeps M193; queue and assignment-rule move to M194 and M195; 795 pins), the dropped-refinements baseline totals (250 schemas, 884 sites) and the llms.txt schema heading (210); generated artifacts regenerated",
        "797aeb468 skills: the automation reference's approver table said a queue approver routes to nobody and must not be authored. This PR made that false, so the row now says what it resolves to",
        "d1a0d738b merge of origin/main for a conflict with main's pending-approver read grant (#26397) in plugin-sharing sharing-service.ts and sharing-plugin.ts and plugin-security explain-engine.ts. Both are kept: the read filter ORs the owner match, the queue-sitting match and the granted ids (record shares plus pending-approval reads); explain lists the approval read grants, then the queue rows",
        "aea6b12d8 skills: the queue approver row fits the reference's token ceiling (check-skills-token-ratchet, red in CI's source-gates lane at d1a0d738b)",
        "290a435af merge of origin/main for main's fix of its own dogfood red (#26406, fixing #26400). Main's #26390 had used the reference's headroom, so the row is shortened again in the merge: members of the named ownership queue at node entry; an empty queue adds nobody"
      ],
      "skills_docs": "Skills-docs: follow-up owed — skills/objectstack-data/SKILL.md and skills/objectstack-data/rules/security.md (queues, the reserved queue column, claim, release and move, the queue sharing recipient), skills/objectstack-automation/SKILL.md (assignment rules), skills/objectstack-platform/SKILL.md (the queues and assignmentRules keys are listed, not taught), the evals of those three skills, and content/docs/permissions/sharing-rules.mdx (the queue recipient). Updated here, but only in part: content/docs/automation/approvals.mdx and the approver table in skills/objectstack-automation/references/state-machines-and-approvals.md teach the queue approver type. No eval exercises it, so the line is owed, not 'updated here'. The ownership-queue authoring guide is ADR-0142 Execution plan item 4, which this card already keeps open.",
      "dogfood_battery": "Full battery at head 290a435af: the closure build (pnpm --filter '@objectstack/dogfood^...' build, 264s), then pnpm --filter @objectstack/dogfood test under os-verify-lock.sh, with no OS_TEST_SHARD, no path and a clean tree. 303 files: 300 passed, 3 skipped, 0 failed. 2552 tests: 2534 passed, 18 skipped, 0 failed (854s). Earlier heads this round: at 45558e255, 300 files, 297 passed, 3 skipped, 0 failed. At a554823c6 and d1a0d738b, two files were red: test/authz-conformance.test.ts and test/authz-probe-blind-spot.test.ts. Both were main's own red (#26400): main's #26361 added a REST route row without re-measuring the census, and every other file passed. Main's fix #26406 landed, 290a435af merges it, and both files pass at this head.",
      "gates": "node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack at head 290a435af derived 163 commands. Since e45133760, main folded several node-script-plus-self-test pairs into single pnpm check scripts. All 163 ran at this head after the battery, each exit code captured before any pipe, and every one was 0. check:type-check-debt ran under os-verify-lock.sh. dispatch-gates --ran: 163 derived, 163 run, 0 NOT-MEASURED, 0 UNRUN. Outside the union: node scripts/check-skills-token-ratchet.mjs and its --self-test exit 0 at this head.",
      "tests": "At head 290a435af: objectql src/ownership-queue.test.ts 23 / 23, and with src/registry 40 files / 531 tests; spec src/migrations plus src/type-alias-convention.pin.test.ts 6 files / 234 tests; spec check:generated and check:llms-txt exit 0 after regeneration. At d1a0d738b, after the conflict merge: plugin-sharing 57 files / 1278 tests, plugin-approvals 101 / 1294, plugin-security 230 / 5000 passed (45 pre-existing skips), and all three packages' typecheck scripts exit 0.",
      "landing_head_note": "For the seat to replace the body's stale Tests and gates lines: 'At head 290a435af: CI 64 check runs, 59 success, 5 skipped by path, 0 failed. Full dogfood battery 303 files, 300 passed, 3 skipped, 0 failed (2552 tests, 2534 passed, 18 skipped). Gate union 163 derived, 163 run, every one exit 0. Six merges of main, each on a conflict or a main-caused red: three for pin counts and generated references, one for main's moved error-code ledger, one for the pending-approver read grant (#26397), and one for main's census fix (#26406).'",
      "adr_open_items_sentence": "Kept out of this PR, as docs/adr/** is governed. Text for the director seat or the maintainer to lift verbatim into ADR-0142 Open items: 'Whether the queue column is injected on every ownership: user object (D3 as accepted) or moves to a per-object opt-in was put to the maintainer in objectstack#26359, who confirmed D3 as accepted (ruling A, https://github.com/objectstack-ai/objectstack/issues/26359#issuecomment-6429748166).'",
      "line_budget": "187 files, +6483 / -408 against main. Still Tier H.",
      "mcp_calls": "GitHub MCP reads only: pull_request_read (get, check runs, status), actions_list (workflow runs), get_job_logs, search_pull_requests, search_issues. No MCP write tool was used.",
      "api_writes": "1 relay dispatch: this comment, through scripts/pm/post-stamped.mjs. Git pushes to claude/project-thread-g33c7k landed 45558e255, a554823c6, 797aeb468, d1a0d738b, aea6b12d8 and 290a435af. There were no body, label, review, queue or auto-merge writes.",
      "open_questions": "Unchanged: the queues RLS membership key (recommendation A, a follow-up on this card). The body keeps Part of #25769.",
      "next": "Seat: patch the body (landing_head_note, the Skills-docs line), file the owed skills-docs card and rewrite the line to its number, then ask the reviewing seat to re-review head 290a435af. Re-arm only on a PASS."
    }

    Generated by Claude Code

  6. objectstack-fleet commented on Oct 27, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
      "issue": 25769,
      "status": "done",
      "round": "merge of main for a conflict on PR #26337 (mergeable_state dirty at 290a435af), for the director's re-review",
      "branch": "claude/project-thread-g33c7k",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/26337",
      "head": "cbd27d9a6c151b99be44390df3bd589d1ac3dbb8",
      "previous_head": "290a435afcbe1127dda5d09d7d0330d8e7522429 (report 6433798870)",
      "session": "session_01GTntg542RUmmRRbMY6wMZD",
      "check_runs": "At head cbd27d9a6, at 11:09Z: 62 check runs, 61 completed (56 success, 5 skipped by path selection: Dogfood Regression Gate shards, Dogfood Verify CLI, Temporal Conformance, Packed-tarball smoke, 18.x upgrade harness), 0 failed. TypeScript Type Check and Test UI aggregates are green. Test Core (5/8) was still running when this was posted, so the Test Core aggregate is not yet reported; its result goes to the seat when it finishes.",
      "mergeability": "mergeable_state is blocked (review), not dirty. A merge-tree of this head against main 8c0306f5d is clean.",
      "conflicts": [
        "content/docs/concepts/metadata-lifecycle.mdx: this branch had moved the DEFAULT_METADATA_TYPE_REGISTRY type count (29 to 31); main rewrote the sentence count-free. Main's side is taken.",
        "content/docs/getting-started/quick-reference.mdx: this branch had moved two heading counts (Automation 3 of 15, Security 3 of 6); main dropped the counts from both headings. Main's side is taken.",
        "packages/spec/src/kernel/metadata-type-schemas.test.ts: this branch had moved the closed/total pin to 29 / 30 for queue and assignment_rule; main replaced the pin with a test that computes the open set from the registry and requires it to equal STILL_STRIP. Main's side is taken. Both new types are strictObject, so they are closed and the computed test covers them (it passes at this head)."
      ],
      "skill_trim": "After main's own change to skills/objectstack-platform/SKILL.md, the file with this branch's two added keys (queues, assignmentRules) measured 5998 tokens against a ceiling of 5997. The approvals sentence lost two words: 'an approval is authored as a flow with Approval nodes' became 'an approval is a flow with Approval nodes'. It now measures 5995 (headroom 2). node scripts/check-skills-token-ratchet.mjs and its --self-test, check:skill-top-level-keys, check:skill-identifier-liveness, check:skill-frame-sync and check:skill-compatibility all exit 0.",
      "regeneration": "The os-regen driver deferred content/docs/references/kernel/metadata-plugin.mdx. Regenerated from the merged tree (gen:schema, spec build, gen:export-origins, gen:api-surface, gen:docs, gen:liveness-counts, gen:migration-registry, gen:upgrade-guide); check:generated, check:llms-txt and check-regen-pending exit 0.",
      "dogfood_battery": "Rerun, because the merge brought main code onto this PR's surfaces (objectql engine.ts, plugin-approvals approval-service.ts, runtime activation-gate.ts, catalog-activation.ts and route-ledger.ts, the authz conformance matrix). Full battery at head cbd27d9a6: the closure build (pnpm --filter '@objectstack/dogfood^...' build, 398s), then pnpm --filter @objectstack/dogfood test under os-verify-lock.sh, with no OS_TEST_SHARD, no path and a clean tree. 304 files: 301 passed, 3 skipped, 0 failed. 2519 tests: 2501 passed, 18 skipped, 0 failed.",
      "tests": "spec src/kernel/metadata-type-schemas.test.ts, src/type-alias-convention.pin.test.ts, src/migrations, src/security and src/automation/assignment-rule at this head: 21 files / 767 tests passed.",
      "gates": "The gate union was not rerun this round; the seat's instruction for this merge asked for the head, the check runs, the conflict files and the battery. The last full union is at 290a435af (163 run, every one exit 0, report 6433798870).",
      "review_findings": "Unchanged from report 6433798870: ①-1 fixed in 45558e255, ②-1 covered by the seat's body and title patch, ③-1 lifted by the director into PR #26447. This merge touches none of them.",
      "mcp_calls": "GitHub MCP reads only: pull_request_read (get, check runs), get_check_run, get_job_logs. No MCP write tool was used.",
      "api_writes": "1 relay dispatch: this comment, through scripts/pm/post-stamped.mjs. 1 git push to claude/project-thread-g33c7k (290a435af to cbd27d9a6). There were no body, label, review, queue or auto-merge writes.",
      "next": "Director: re-review head cbd27d9a6. Seat: re-arm only on a PASS."
    }

    Generated by Claude Code

  7. objectstack-fleet commented on Oct 27, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
      "issue": 25769,
      "status": "done",
      "round": "merge of main for a conflict on PR #26337 (mergeable_state dirty at cbd27d9a6, after contract review 6441855511 PASSed that head)",
      "branch": "claude/project-thread-g33c7k",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/26337",
      "head": "f35f41144923f9a0edcfe2d158bfcfd319fcab02",
      "previous_head": "cbd27d9a6c151b99be44390df3bd589d1ac3dbb8 (report 6440422769, review 6441855511 PASS)",
      "session": "session_01GTntg542RUmmRRbMY6wMZD",
      "merge": "f35f41144 merges origin/main fe53769a8 (20 commits since the previous merge base 7c34e5dc2) into cbd27d9a6. Its only commit is the merge.",
      "check_runs": "At head f35f41144, all 62 check runs have completed: 57 success, 5 skipped by path selection (Dogfood Regression Gate shards, Dogfood Verify CLI, Temporal Conformance, Packed-tarball smoke, 18.x upgrade harness), 0 failed. The aggregates Test Core, Test UI, TypeScript Type Check and Lint & Repo Gates are green.",
      "mergeability": "mergeable_state is blocked (review), not dirty. Main has since moved to f6ffd7234 (8 commits); a merge-tree of this head against it is clean.",
      "conflicts": [
        "packages/spec/src/type-alias-convention.pin.test.ts: counts only. Main moved the isomorphic pin from 791 to 792 (#25785); this branch adds 4. Resolved to 796, keeping main's comment block for 791 to 792 and, after it, this branch's block for 792 to 796 (ADR-0142 phase 2).",
        "packages/spec/dropped-refinements.baseline.json: counts only. Main's header is 248 schemas / 869 sites; this branch adds 3 / 18. Resolved to 251 / 887. gen:schema verifies the header against the entries and exits 0."
      ],
      "deferred_generated": "The os-regen driver deferred seven generated files. packages/spec/authorable-surface/automation.json and security.json were rebuilt as main's version plus this branch's added keys only (AssignmentRule, AssignmentRuleEntry, AssignmentTarget, DeclaredQueueMember, Queue: 33 lines, the same 33 as at cbd27d9a6). The text merge had kept ten '[RETIRED]' lines that main's #26599 deleted, and gen:schema refused them as disappeared keys. Five reference pages under content/docs/references/ were regenerated from the merged tree (gen:schema, spec build, gen:export-origins, gen:api-surface, gen:docs, gen:liveness-counts, gen:migration-registry, gen:upgrade-guide). check:generated, check:llms-txt and scripts/check-regen-pending.mjs exit 0.",
      "hunks": "Per file, the added and removed lines of git diff 7c34e5dc2 cbd27d9a6 were compared with those of git diff fe53769a8 f35f41144. 180 of the 184 files are byte-identical. packages/runtime/src/domains/activation-gate.ts is byte-identical with three lines of context; with zero context the diff aligns a closing brace one line differently, because main's #26605 edited the same file further down. The other three files differ in count lines only: the two conflict files above and content/docs/references/index.mdx, which is generated (main's base schema count moved 1548 to 1549, so this branch's line reads 1556).",
      "scope": "Yes, main's merge touched files in the review's scope beyond counts and generated output. Four code files this PR edits also changed on main, each auto-merged with no hunk overlapping this diff: packages/objectql/src/engine.ts (378c940b1, #26645, moves the ReadableIds composition and permission-resolution bodies out of the file, 59 insertions and 204 deletions), packages/runtime/src/domains/activation-gate.ts (8c0306f5d, #26605, adds activationCaller for the flow toggle), packages/spec/src/stack.zod.ts and packages/lint/src/authoring-rules.ts (dbf7e04ad, the 16.x retirement-kit age-out, 1 to 3 lines each). This PR's own lines in those files are unchanged, as the hunk check shows.",
      "dogfood_battery": "Rerun, because the merge brought main code onto this PR's surfaces. Full battery at head f35f41144: the closure build (pnpm --filter '@objectstack/dogfood^...' build, 389s), then pnpm --filter @objectstack/dogfood test under os-verify-lock.sh, with no OS_TEST_SHARD, no path and a clean tree (1122s). 304 files: 301 passed, 3 skipped, 0 failed. 2521 tests: 2503 passed, 18 skipped, 0 failed.",
      "tests": "spec src/kernel/metadata-type-schemas.test.ts, src/type-alias-convention.pin.test.ts, src/migrations, src/security and src/automation/assignment-rule at this head, under the lock: 21 files / 722 tests passed. node scripts/check-skills-token-ratchet.mjs exits 0.",
      "gates": "The gate union was not rerun this round, as in the previous merge round; the seat asked for the head, the check runs, the conflict files, the scope answer and the battery. The last full union is at 290a435af (163 run, every one exit 0, report 6433798870).",
      "review_findings": "Contract review 6441855511 PASSed cbd27d9a6. Its three should-fix items are not taken in this PR: the stale body prose is the seat's, the assignment user-target existence check is filed by the seat as its own card, and the queue-approver dogfood matrix row is taken by the seat as noted. This merge touches none of them.",
      "mcp_calls": "GitHub MCP reads only: pull_request_read (get, check runs), get_check_run. No MCP write tool was used.",
      "api_writes": "1 relay dispatch: this comment, through scripts/pm/post-stamped.mjs. 1 git push to claude/project-thread-g33c7k (cbd27d9a6 to f35f41144). There were no body, label, review, queue or auto-merge writes.",
      "delta_for_review": "Triage note 6442643190 says review 6441855511 does not govern this head and a delta review of the resolved files is owed. Measured per file, git diff cbd27d9a6 f35f41144 equals main's own change (git diff 7c34e5dc2 fe53769a8) in every file but three: packages/spec/src/type-alias-convention.pin.test.ts and packages/spec/dropped-refinements.baseline.json (the two conflict resolutions, count lines only) and content/docs/references/index.mdx (generated: the total schema count reads 1556). The authorable-surface baselines, the other four regenerated pages and activation-gate.ts carry main's change and nothing else.",
      "next": "Seat: arrange the delta review the triage note asks for (this PR's seat, or triage on a Contract-review-handoff line), then re-arm on its PASS."
    }

    Generated by Claude Code

  8. objectstack-fleet commented on Oct 27, 2026

    @objectstack-fleet
    ContributorAuthor

    ACCEPT → PR #26337 comment 6442722673 (seat domain:spec#4, 2026-10-27T13:11Z). Contract review 6441855511 PASS carried to f35f41144 by the seat delta review. Tier H: os-zhuang APPROVED. The card stays open after the merge for the queues RLS key (decision pending with the user) and ADR-0142 plan item 4.

  9. objectstack-fleet commented on Oct 27, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
      "issue": 25769,
      "status": "done",
      "round": "merge of main after the merge queue removed PR #26337 for MERGE_CONFLICT (14:16Z, head f35f41144)",
      "branch": "claude/project-thread-g33c7k",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/26337",
      "head": "d6bbeaeb4eada74dc9e266fdfa25ac058ce4af7e",
      "previous_head": "f35f41144923f9a0edcfe2d158bfcfd319fcab02 (report 6442677059, seat record 6442722673)",
      "session": "session_01GTntg542RUmmRRbMY6wMZD",
      "merge": "d6bbeaeb4 merges origin/main 1685a06dd (6 commits past f6ffd7234, 14 past the previous merge base fe53769a8) into f35f41144. Its only commit is the merge.",
      "check_runs": "At head d6bbeaeb4, all 62 check runs have completed: 57 success, 5 skipped by path selection (Dogfood Regression Gate shards, Dogfood Verify CLI, Temporal Conformance, Packed-tarball smoke, 18.x upgrade harness), 0 failed. The aggregates Test Core, Test UI, TypeScript Type Check and Lint & Repo Gates are green.",
      "mergeability": "A merge-tree of this head against main is clean, both at 1685a06dd and at 74db43ef3 (read after CI finished).",
      "conflicts": [
        "packages/platform-objects/src/apps/translations/object-lifecycle-panel-echo-decisions.test.ts: counts only. The metadata-forms positive control moved 683 to 686 on main (#26548, the report form's period and export rows); this branch adds 2 (the queue and assignment_rule type-level display pairs). Resolved to 688, with main's comment first and this branch's after it. The translation tests (25 files / 438 tests) pass at 688."
      ],
      "regeneration": "Nothing was deferred by the os-regen driver. The regen run (gen:schema through gen:upgrade-guide) changed no file; check:generated, check:llms-txt, scripts/check-regen-pending.mjs and node scripts/check-skills-token-ratchet.mjs exit 0.",
      "hunks": "Per file, the added and removed lines of git diff fe53769a8 f35f41144 were compared with those of git diff 1685a06dd d6bbeaeb4. 183 of the 184 files are byte-identical. The other is the conflict file, which differs in its count line and comment only.",
      "delta_for_review": "Measured per file, git diff f35f41144 d6bbeaeb4 equals main's own change (git diff fe53769a8 1685a06dd) in every file but one: the conflict file above (count line and comment only).",
      "scope": "Main auto-merged code into files this PR edits, with no hunk overlapping this diff: packages/objectql/src/engine.ts (af1e1e0c8, a child rule reading a parent summary counts earlier admitted rows of the same bulk create), packages/lint/src/index.ts and rule-explanations.ts, the four metadata-forms translation files under packages/platform-objects/src/apps/translations/, and packages/spec/scripts/liveness/empty-state-registry.mts.",
      "dogfood_battery": "Rerun, because engine.ts is on this PR's surface. Full battery at head d6bbeaeb4: the closure build (pnpm --filter '@objectstack/dogfood^...' build, 372s), then pnpm --filter @objectstack/dogfood test under os-verify-lock.sh, with no OS_TEST_SHARD, no path and a clean tree (1151s). 305 files: 302 passed, 3 skipped, 0 failed. 2527 tests: 2507 passed, 20 skipped, 0 failed.",
      "tests": "At this head, under the lock: platform-objects src/apps/translations 25 files / 438 tests; spec src/kernel/metadata-type-schemas.test.ts, src/type-alias-convention.pin.test.ts, src/migrations, src/security and src/automation/assignment-rule 21 files / 722 tests. All passed.",
      "gates": "The gate union was not rerun this round, as in the two previous merge rounds. The last full union is at 290a435af (163 run, every one exit 0, report 6433798870).",
      "correction": "Report 6442677059 said the seat files the assignment user-target existence check as its own card. Per the seat record 6442722673, it is noted there and not filed, because it has no reach yet.",
      "mcp_calls": "GitHub MCP reads only: pull_request_read (get, check runs), get_check_run. No MCP write tool was used.",
      "api_writes": "1 relay dispatch: this comment, through scripts/pm/post-stamped.mjs. 1 git push to claude/project-thread-g33c7k (f35f41144 to d6bbeaeb4). There were no body, label, review, queue or auto-merge writes.",
      "next": "Seat: delta review of the one count line, then re-arm."
    }

    Generated by Claude Code

  10. objectstack-fleet commented on Oct 27, 2026

    @objectstack-fleet
    ContributorAuthor

    Release: session_01HbmCEPMBmMLU3VZCEzfec7 / card thread session_01GTntg542RUmmRRbMY6wMZD (zhuangjianguo, domain:spec#4, claim 6415635954), 2026-10-27T15:22Z
    Resume-from: none

    Landed.

    Reading Result
    PR #26337 object merged by the queue from head d6bbeaeb4
    origin/main a9f654ebf feat!: ownership queues and assignment rules (ADR-0142 phase 2) (#26337)

    Why this card is released. Seat 4 is clocking out. The user stopped new dispatch on both spec seats on 2026-10-27 at 00:20Z, and a new spec seat opens elsewhere.

    What the card still carries. These are ADR-0142 items that PR #26337 did not carry:

    1. The queues RLS membership key. This needs a decision, so the card now carries needs-user-decision. The contract has one IRlsMembershipResolver slot, which an app's resolver also fills, and the producer screens RESERVED_RLS_MEMBERSHIP_KEYS out of any resolver's answer. That leaves three options:

      • A. Reserve queues and have plugin-security resolve it from the ownership-queue service, the same way it resolves positions.
      • B. plugin-sharing registers its own resolver. This contradicts the reserved-key contract.
      • C. Drop the key from the plan. That means amending the accepted ADR.

      os-decision-facets

      • ① Long-term soundness: A gives the key one kernel-side producer, the same shape as positions. B makes the key's value depend on which resolver won the slot. C leaves a gap the ADR names.
      • ② Business pull: today no RLS policy reads current_user.queues. Claim and access already work through the sharing path in feat!: ownership queues and assignment rules (ADR-0142 phase 2) #26337.
      • ③ AI-error-proofing: A fails closed. An app resolver that tries to supply queues is screened out, so it cannot silently clobber membership.
      • ④ Startup non-expansion: A is a small follow-up on this card, not a new surface.

      Prior rulings read: ADR-0142 Execution plan item 1, RESERVED_RLS_MEMBERSHIP_KEYS, decision [Decision] ADR-0142 D3: inject the queue column on every ownership: 'user' object (the default, so every business object today) or only where an object opts in (Salesforce "Allow queues") #26359 (D3, closed). Thread: os-dev-report 6428186578.

      Seat recommendation: A. The question was also put to the user in the seat thread, and no answer has come yet.

    2. The rest of the ADR-0142 plan. These items need no decision and resume once the ruling is in: delete the HotCRM stopgap, add the Console queue picker and Claim affordance, and write the authoring guide (Execution plan item 4).

    3. Skills docs. These are filed separately as skills(data,automation,platform): teach ownership queues and assignment rules (ADR-0142 phase 2, PR #26337) with eval prompts #26475.

  11. objectstack-fleet commented on Oct 27, 2026

    @objectstack-fleet
    ContributorAuthor

    Brief-claimed-by: session_01KrKXQVvgYk2AJ4VkqMobyb · batch #415 · 2026-10-27T22:56Z

    Director seat, summon #51 continuation (ledger objectstack#12708). Presented to the maintainer in batch #415 as item 5 of 5 — the one open item the spec seat left on this parent after PR #26337 landed (release 6445967026): the queues RLS membership key. Seat increment (re-verified on origin/main aa00362fe5):

    • Premises hold: packages/spec/src/contracts/rls-membership-resolver.ts:64 declares the one IRlsMembershipResolver slot; :89 RESERVED_RLS_MEMBERSHIP_KEYS = id, organization_id, positions, org_user_ids, accessible_org_ids, email — positions is the kernel-produced precedent A copies; queues is not reserved today. PR feat!: ownership queues and assignment rules (ADR-0142 phase 2) #26337 merged (a9f654ebf); D3's access path goes through the sharing owner match and does not need the key, so no RLS policy reads current_user.queues yet.
    • Half-state: needs-user-decision alone on a p1 parent; the ruling's stroke returns it to pm:queue for the remaining execution-plan items.
    • Facets (the seat's block, re-read): ① A gives the key one kernel-side producer (plugin-security from the ownership-queue service), the positions shape; B makes the value depend on which resolver won the slot; C amends an accepted ADR to drop a named key. ② no policy reads it today; ③ A fails closed (an app resolver supplying queues is screened out); ④ a small follow-up on this card, no new surface.
    • The seat agrees with A. Not B (contradicts the reserved-key contract) and not C (an ADR amendment to remove a capability the record names). Workload: server (plugin-security) · 1 PR · S, as a child of this card beside the HotCRM stopgap deletion, the Console queue picker / Claim affordance and the authoring guide (ADR-0142 execution plan).
      Prior rulings read: ADR-0142 Execution plan item 1, [Decision] ADR-0142 D3: inject the queue column on every ownership: 'user' object (the default, so every business object today) or only where an object opts in (Salesforce "Allow queues") #26359 A (D3), 6429748166; thread: 6428186578, 6445967026.
  12. objectstack-fleet commented on Oct 28, 2026

    @objectstack-fleet
    ContributorAuthor

    Ruling: batch #415 item 5 · letter A (the queues RLS membership key) · maintainer 「同意」 2026-10-28T00:36Z

    Recorded by the director seat (summon #51 continuation, session_01KrKXQVvgYk2AJ4VkqMobyb, ledger objectstack#12708). The maintainer answered batch #415 with 「同意」 — every seat letter. Brief 6455628190; the spec seat's release 6445967026 put the question. Letter A: queues joins RESERVED_RLS_MEMBERSHIP_KEYS (packages/spec/src/contracts/rls-membership-resolver.ts:89), and plugin-security resolves it from the ownership-queue service into current_user.queues the way it resolves positions — one kernel-side producer; an app resolver that supplies queues is screened out (fails closed). Not B (plugin-sharing's own resolver, against the reserved-key contract) and not C (an amendment to the accepted ADR-0142 to drop a named key).

    Workload: server (plugin-security) · 1 PR · S, a child of this card (Clause-②: yes — a reserved key is added to a published list; the lane declares the arm; Metadata-protocol: none). The rest of the ADR-0142 execution plan resumes beside it: the HotCRM stopgap deletion (after a published release), the Console queue picker and Claim affordance (objectui lane), the authoring guide (item 4); skills docs are #26475.

    Execution: needs-user-decision → pm:queue in this act (the parent stays domain:spec, p1, area:automation); the next spec seat files the child. Ruling-ref: names this comment.

  13. objectstack-fleet commented on Oct 28, 2026

    @objectstack-fleet
    ContributorAuthor

    Child filed · domain:spec seat 1 (#6017) · session session_01WGufzfhobWEgUUrjz4rrbh · 2026-10-28T01:31Z

    Ruling 6457475657 (letter A) is filed as #27016. That child adds queues to RESERVED_RLS_MEMBERSHIP_KEYS and has plugin-security resolve current_user.queues from the ownership-queue membership, the same way it resolves positions. Seat 1 claims it; the claim follows on the child. This parent stays pm:queue for the rest of the ADR-0142 execution plan: the HotCRM stopgap deletion, the Console queue picker and Claim affordance, and the authoring guide.

  14. objectstack-fleet commented on Oct 28, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 3 · 2026-10-28T11:34Z
    Session: session_01WGufzgbJhFoXYsLSe5WSPP
    Account: os-support-ai
    Branch: claude/project-thread-8qr81n (card thread; the platform assigns the thread's branch and it can push only that one, written as measured instead of claude/issue-25769-<slug>)
    Worktree: objectstack-issue-25769
    Domain: domain:spec
    Seat: domain:spec#3
    Ruling-ref: 6457475657 (letter A, the queues key, landed via #27016); ADR-0142 as accepted (phase 1, PR #25816); this claim carries ADR-0142 Execution plan items 3 (Console) and 4 (authoring guide)
    File surface: ui/packages/** for the Console queue picker (approver and share-recipient types; app-shell/.../inspectors/FlowReferenceField.tsx placeholder), the Claim affordance ({ owner_id: <self> } through the normal update path), and the "sitting in queue" filter; their tests; one authoring guide under content/docs/** plus prose links; one changeset per touched published package. ⛔ Not packages/spec/**, skills/** (#26475), docs/adr/**, or HotCRM (plan item 2)(stop on breach; explain in the report) Container & model:M, mode:thread, model: TIER_DEFAULT — --tier: no path-derived mandate (ui reader of a landed protocol; one CONTRACT_REVIEW_TIER review owed, run by the seat), effort: highClause-②: no Metadata-protocol: none Responsibility: the remainder of this card after PR #26337 and #27016; first claim wins across lanes;Part of #25769(HotCRM item stays) Thread-read: 6445967026 Premise: holds onorigin/main ae16687: FlowReferenceField.tsx(~:967) renders aqueue` reference as text "until the console's two-source queue picker lands"; no Console surface offers Claim or a parked-record filter
    Serial constraints cleared: no open PR on these ui surfaces that the seat knows of; the dev re-checks before editing

  15. objectstack-fleet commented on Oct 28, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report
    {
    "issue": 25769,
    "status": "done",
    "branch": "claude/project-thread-8qr81n",
    "pr": "#27264",
    "session": "session_01WGufzfFCwcM21eGjVuqwRz",
    "premise_still_valid": true,
    "summary": "ADR-0142 plan items 3 and 4. Console: the queue approver Value picker (FlowReferenceField placeholder replaced; driven by the published registry-and-data binding) and the sharing-rule queue recipient both list declared queues plus sys_queue rows by name; Claim on a record sitting in a queue renders only on an explain transfer answer carrying queue_claim:admits (fails closed) and sends {owner_id:}, a 409 CONCURRENT_UPDATE shown as taken; an In-a-queue list toggle (owner_id is_null AND queue is_not_null) offered only on objects served with the injected system queue column. Docs: content/docs/automation/queues-and-assignment-rules.mdx, linked from automation/index, approvals, sharing-rules, rls. No spec change, no skills/** or docs/adr/**.",
    "tests": "4 new files, 35 tests pass (VERDICT command-exit 0). Locked suites at 4dde047: plugin-detail+i18n+fields recipient/queue 416 files 4361 passed/31 skipped; app-shell scope 103 files 945 passed/1 skipped; plugin-list 168 files 1674 passed; each VERDICT command-exit 0. type-check of fields, plugin-detail, plugin-list, i18n, app-shell: each VERDICT command-exit 0. One combined suite run exceeded the session's 30-minute limit and was split (not narrowed).",
    "gates": "dispatch-gates --commands: 78 commands, final all exit 0. First pass: check:role-word exit 1 (new guide said role:; reworded in 4dde047, rerun exit 0); ui vitest scripts/ exit 1 (3 tests timed out at 15s under shared-box load; rerun exit 0, 5019 passed/2 skipped); check:skill-examples exit 3 (client-react unbuilt; built, rerun exit 0); check:type-check-debt exit 3 (no lock turn; rerun under lock exit 0). --ran: 78 derived, 78 run, 0 NOT-MEASURED, 0 UNRUN. CI check-runs: not yet concluded at report time.",
    "dogfood_battery": "n/a — no ! in the PR title and no (narrowing) arm",
    "mcp_calls": "2 — mcp__github__search_pull_requests, mcp__github__pull_request_read (reads only)",
    "api_writes": "2 — fleet-write relay: pr_create (#27264, draft, assignee os-support-ai, label documentation); comment (this os-dev-report on #25769). Plus git push of the branch.",
    "open_questions": [],
    "out_of_scope_findings": [
    "carrier: none · noted, not filed — the approver read face outside the editor still shows a stored queue by machine name (Acceptance notes)"
    ]
    }


    Generated by Claude Code

  16. objectstack-fleet commented on Oct 28, 2026

    @objectstack-fleet
    ContributorAuthor

    ACCEPT → PR #27264 comment 6471422040 (ADR-0142 plan items 3 + 4)

  17. objectstack-fleet commented on Oct 28, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed, partial · domain:spec seat 3 · os-support-ai · 2026-10-28T14:34Z

    reading value
    PR #27264 merged through the queue at 2026-10-28T14:34Z, merge commit 2302b92b1b
    origin/main contains the merge commit (git merge-base --is-ancestor)

    Delivered (ADR-0142 execution plan items 3 and 4):

    • Console. The approver and sharing-recipient pickers offer queues from both sources: declared queue items and the organization's sys_queue rows. A record sitting in a queue shows Claim only on the server's explain queue_claim: admits answer. The claim sends { owner_id: <self> } through the normal update, and a lost race is reported as "someone else claimed it". Lists of an object with the injected queue column have an In a queue toggle (owner_id empty, queue set).
    • Docs. content/docs/automation/queues-and-assignment-rules.mdx explains how to declare a queue and an assignment rule, the load requirement, what a parked record is and who sees it, how a claim is spelled, and why a queue is not a messaging audience. The approvals, sharing-rules and RLS pages link to it.

    What this card still carries. Plan item 1 (the queues RLS key) closed with #27016. The remaining pieces sit in other lanes:

    pm:dispatched → pm:triage, so triage routes or closes the HotCRM remainder. ⛔ Not a claim.

  18. objectstack-fleet commented on Oct 28, 2026

    @objectstack-fleet
    ContributorAuthor

    triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U

    Path: 真挡得住的权限 / 审批与自动化 | none | P②

    Triage: remainder routed to repo:hotcrm · p1 kept · 2026-10-28T15:04Z

    ⛔ Not a claim.


    Generated by Claude Code

  19. added
    repo:hotcrmSeam card: cross-repo ordering with hotcrm is the substance (pure hotcrm fixes live in hotcrm)
    and removed on Oct 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

area:automationenhancementNew feature or requestpm:queuepriority:p1High: required for production / M2repo:hotcrmSeam card: cross-repo ordering with hotcrm is the substance (pure hotcrm fixes live in hotcrm)

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions