Skip to content

feat(platform-objects)!: Setup's organization, team, business-unit and user records carry no Discussion feed (enable.feeds: false) - #23869

Merged
objectstack-fleet[bot] merged 5 commits into
mainfrom
claude/issue-23838-identity-feeds-off
Oct 16, 2026
Merged

objectstack-fleet[bot] merged 5 commits into
mainfrom
claude/issue-23838-identity-feeds-off

Conversation

@objectstack-fleet

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

Copy link
Copy Markdown
Contributor

Fixes #23838

Clause-②: no (narrowing: the comment create door refuses on four platform objects that accept it today)

What changes

sys_organization, sys_team, sys_business_unit and sys_user (packages/platform-objects/src/identity/) declared no enable.feeds, so they took the spec default (true) and the console drew "Discussion (0)" with a comment composer on every identity record in Setup (objectui#12614 item 1). Each enable: block now declares feeds: false, with a two-line comment naming the reason. No other line in those files moves.

Both consumers of the flag already exist, so nothing else changes:

  • the console reads objectDef?.enable?.feeds !== false (objectui packages/app-shell/src/views/RecordDetailView.tsx:1754 at objectui 63d00da) and strips the Discussion nodes when it is false;
  • plugin-audit's enforceFeedsCapability (packages/plugins/plugin-audit/src/audit-writers.ts, beforeInsert and beforeUpdate on sys_comment) refuses a comment whose thread_id names an object with enable.feeds: false, with the existing 403 FEEDS_DISABLED. No new error code.

The changeset (.changeset/23838-identity-feeds-off.md) is a minor breaking entry under the launch-window convention, with the same Clause-② line and an ADR-0087 not-required (no-migration-prescription) disposition: no spec key, export or stored shape moves, and stored comment rows are kept.

Measured through the public door

CRM app booted --fresh on a random port from this branch (platform-objects and plugin-audit closure rebuilt at 4e5399c4b), signed in as the seeded admin:

request answer
POST /api/v1/data/sys_comment with thread_id sys_user:USER_ID 403 {"code":"FEEDS_DISABLED","object":"sys_user"}
the same with sys_organization:ORG_ID 403 {"code":"FEEDS_DISABLED","object":"sys_organization"}
CONTROL: the same with crm_account:ACCOUNT_ID 201, row created
GET /api/v1/meta/object/NAME, the four identity objects enable.feeds = false on all four (what the console reads)
GET /api/v1/meta/object/crm_account enable.feeds absent (the console reads absent as on)

The server was stopped after the probe (its PID only); its tempdir is gone.

Producer search (dispatch assumption 2): no platform code writes a comment into these threads

Searched at the branch base 66d456d01:

  • every quoted sys_comment in non-test code: the only writers are plugin-audit's own hooks (the feeds gate, comment-access-hooks.ts, the mention hook, which writes notifications, not comments) and the CLI's comment-reactions migration (packages/cli/src/utils/comment-reactions-conversion.ts), which inserts sys_comment_reaction rows only;
  • every quoted or templated thread literal naming one of the four objects ('sys_user:, 'sys_organization:, 'sys_team:, 'sys_business_unit:): hits only in the sys_comment.thread_id description example and its four translation bundles, one parseCommentThreadId unit test and one driver-test code comment, none a writer;
  • every thread_id assignment and every OBJECT:ID template near comment code in non-test sources: reads and keys only (the access hooks' visibility filter, a mention dedup key, a cache key);
  • examples/** and every seed or fixture path: no sys_comment rows; the dogfood comment fixtures use their own four cmt_* objects;
  • objectui at 63d00da: the record page creates sys_comment only from the Discussion composer, which is behind the same feedsEnabled read.

Not searched: the cloud repository, which is not in this container.

Pins

One file, packages/plugins/plugin-audit/src/identity-objects-feeds-off.test.ts. It boots a real ObjectQL over a stub driver with the REAL four definitions imported from @objectstack/platform-objects/identity (aliased to source in this package's vitest.config.ts, so the verdict is about the checkout, not dist/) and the real installAuditWriters hooks:

  • per object (it.each): a new comment on one of its records rejects with code: 'FEEDS_DISABLED', status: 403 and the object named, and no row lands;
  • grandfathered row on sys_user: the gate is first shown live on that exact thread, then a row written below every hook (what a row stored before this change is) stays readable through find, and a body edit without thread_id still saves;
  • CONTROL: a business object that never mentions enable.feeds still accepts a comment.

The pins live in plugin-audit because @objectstack/platform-objects has no runtime dependency on objectql or plugin-audit (plugin-audit depends on platform-objects; the reverse would be a cycle), so the real gate cannot be exercised there. This file is domain:services territory, as the claim anticipated. The generic gate stays pinned where it was: audit-writers.test.ts (insert) and capability-gate-update-verb.test.ts (update verb and the grandfathered edit).

Ablation (one-time proof, not kept)

Each leg ran after the fix was committed, through node scripts/ablation-replace.mjs in WRAP mode (literal anchor, on-disk counts, blob hash before and after, restore proven by blob equal to HEAD and an empty git diff HEAD), running pnpm --filter @objectstack/plugin-audit exec vitest run --maxWorkers=2 src/identity-objects-feeds-off.test.ts. No build or dist/ leg is owed: the identity definitions resolve to src/ through the alias, and the gate mutation is in the package under test.

mutation anchor blob before, after result
delete feeds: false, in sys-user.object.ts 1 to 0 df41d5b3c3f3, 84847d0be0b7 2 failed / 4 passed: the sys_user case and the grandfathered-row case
delete it in sys-organization.object.ts 1 to 0 cfcbe12495aa, 33e67fccd9dd 1 failed / 5 passed: the sys_organization case
delete it in sys-team.object.ts 1 to 0 3a0954909643, df521d289587 1 failed / 5 passed: the sys_team case
delete it in sys-business-unit.object.ts 1 to 0 0db7f124c9d4, e5f6d7a3d360 1 failed / 5 passed: the sys_business_unit case
invert the gate in audit-writers.ts (feeds === false read as feeds !== true) 1 to 0 f556c52ac945, 4a3379a3fc5f 1 failed / 5 passed: the CONTROL

Every leg restored to its HEAD blob, and the tree was clean after the run.

Tests and gates, on head 4e5399c4b (after merging origin/main a31ff2eb5, which carries #23845)

  • pnpm --filter @objectstack/platform-objects test: 71 files, 1103 tests passed.
  • pnpm --filter @objectstack/plugin-audit test: 52 files, 839 tests passed.
  • pnpm --filter @objectstack/platform-objects --filter @objectstack/plugin-audit typecheck: exit 0; the new file is in plugin-audit's tsconfig.test.json program (--listFiles).
  • node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack: 65 commands, each run with its exit code captured before any pipe, all exit 0; --ran reconciliation: 65 accounted for, 0 NOT-MEASURED, 0 UNRUN.
  • The four artifact-roster gates whose roster sits under a directory this diff touches: check-changeset-fixed, check:authz-resolver, check:error-code-casing, check:filter-alias-parity, all exit 0.
  • Not run locally, CI's: the declared wide-population families, the five path-scheduled jobs (Test Core, Build Core, the dogfood pair, Temporal Conformance) and the workspace type-check lanes.

Acceptance notes


Generated by Claude Code

…le.feeds: false

sys_organization, sys_team, sys_business_unit and sys_user took the
enable.feeds default (true), so the console drew a Discussion feed with a
comment composer on every identity record in Setup. Declaring the flag
false hides the feed and makes plugin-audit's existing enable.feeds gate
refuse a comment create on these objects with 403 FEEDS_DISABLED; rows
stored before the flag stay readable and body-editable.

The pins boot a real ObjectQL with the real identity definitions and the
real installAuditWriters hooks (plugin-audit), one refusal case per object,
the grandfathered-row case on sys_user, and a business-object CONTROL.

Claude-Session: https://claude.ai/code/session_01TQLy3Yq6vF4SDpTXdr3Uwi
Co-authored-by: Claude <noreply@anthropic.com>
…s live on that thread

Claude-Session: https://claude.ai/code/session_01TQLy3Yq6vF4SDpTXdr3Uwi
Co-authored-by: Claude <noreply@anthropic.com>
@github-actions github-actions Bot added size/m documentation Improvements or additions to documentation tests tooling labels Oct 16, 2026
@github-actions

github-actions Bot commented Oct 16, 2026 •

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 2 package(s): @objectstack/platform-objects, @objectstack/plugin-audit, touching 2 documentable anchor(s).

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

  • content/docs/deployment/cli.mdx (via sys_comment (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/permissions/system-context.mdx (via sys_comment (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/plugins/packages.mdx (via sys_comment (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/ui/setup-app.mdx (via sys_comment (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))

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

  • content/docs/releases/v14.mdx (via sys_comment (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/v16.mdx (via sys_comment (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/v17/17-0.mdx (via sys_comment (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/v17/17-1.mdx (via sys_comment (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/v17/17-5.mdx (via sys_comment (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/v17/17-6.mdx (via sys_comment (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 name(s) were too generic to anchor anything (single lowercase words)
  • 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 — 11 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 6422da58e83ac5032030c7daa4787fddf5eeb165 → packageMentionDocs.

Which tree this was computed on

This run read content/docs from be076954b9d126671f9873159a2eb4f807d5f837 — the merge of head 01f606f4b8101cd53d2e93c95d8de97cd549167e into base 6422da58e83ac5032030c7daa4787fddf5eeb165, 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 be076954b9d126671f9873159a2eb4f807d5f837 && git checkout be076954b9d126671f9873159a2eb4f807d5f837
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 6422da58e83ac5032030c7daa4787fddf5eeb165 01f606f4b8101cd53d2e93c95d8de97cd549167e && git checkout -B drift-repro 6422da58e83ac5032030c7daa4787fddf5eeb165 && git merge --no-ff 01f606f4b8101cd53d2e93c95d8de97cd549167e

node scripts/docs-audit/affected-docs.mjs --json 6422da58e83ac5032030c7daa4787fddf5eeb165

⚠️ 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 6422da58e83ac5032030c7daa4787fddf5eeb165 → pass the list as
args.docs, on the commit named under Which tree this was computed on.

…bject thread

The thread_id description and the docblock illustrated the thread format
with `sys_user:abc123`. sys_user now declares enable.feeds: false, so a
comment created by following that example answers 403 FEEDS_DISABLED.
The example becomes `account:9001`, already the docblock's second one.
The zh-CN, ja-JP and es-ES leaves swap only the example; the en bundle is
regenerated from the source in the next commit.

Claude-Session: https://claude.ai/code/session_01TQLy3Yq6vF4SDpTXdr3Uwi
Co-authored-by: Claude <noreply@anthropic.com>
Written by `node scripts/check-i18n-bundles.mjs --write`; the only leaf
that moved is sys_comment.fields.thread_id.help.

Claude-Session: https://claude.ai/code/session_01TQLy3Yq6vF4SDpTXdr3Uwi
Co-authored-by: Claude <noreply@anthropic.com>
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

Contract review

Served-tier: CONTRACT_REVIEW_TIER
Head-sha: 01f606f4b8101cd53d2e93c95d8de97cd549167e
Local-runs: none
Scope: packages/platform-objects/src/identity/sys-organization.object.ts, packages/platform-objects/src/identity/sys-team.object.ts, packages/platform-objects/src/identity/sys-business-unit.object.ts, packages/platform-objects/src/identity/sys-user.object.ts, packages/plugins/plugin-audit/src/identity-objects-feeds-off.test.ts, packages/plugins/plugin-audit/src/objects/sys-comment.object.ts, packages/plugins/plugin-audit/src/translations/en.objects.generated.ts, packages/plugins/plugin-audit/src/translations/zh-CN.objects.generated.ts, packages/plugins/plugin-audit/src/translations/ja-JP.objects.generated.ts, packages/plugins/plugin-audit/src/translations/es-ES.objects.generated.ts + .changeset/23838-identity-feeds-off.md, .changeset/config.json, packages/plugins/plugin-audit/src/audit-writers.ts, packages/plugins/plugin-audit/src/comment-access-hooks.ts, packages/spec/src/data/object.zod.ts, packages/plugins/plugin-audit/vitest.config.ts, packages/plugins/plugin-audit/tsconfig.test.json, .objectui-sha, objectui packages/app-shell/src/views/RecordDetailView.tsx (at the pin daeb77fc and at the cited 63d00da), scripts/pm/clause2-line.mjs, scripts/check-changeset-no-major.mjs, scripts/check-adr-0087-registration.mjs, .github/workflows/pr-automation.yml

① Derived judgments

Diff read as git diff a31ff2eb5..01f606f4b (the merge base with main): 11 files, +285 / −6, identical to the PR's file list.

  1. The declared accept-set narrowing — right. A sys_comment insert or update whose thread_id names sys_organization, sys_team, sys_business_unit or sys_user is now refused. Read in audit-writers.ts: enforceFeedsCapability (:2218–:2233) takes the object off thread_id, resolves it through getObjectDef → engine.getSchema (:1338), and throws code: FEEDS_DISABLED, status: 403, object when def?.enable?.feeds === false; it is registered on both beforeInsert and beforeUpdate for sys_comment (:2234–:2235). The four definitions now carry feeds: false in their enable: blocks and nothing else in those files moves. The gate itself is untouched by the PR; the narrowing is entirely the metadata flip, at the one hook seam every caller crosses (REST, SDK, engine), as the changeset says.
  2. The grandfather half — right. On update an absent thread_id returns before the check (:2219–:2222), so a body edit on a stored row still saves; the read path carries no feeds gate at all — comment-access-hooks.ts never reads enable.feeds (its own header, :84, calls the two gates orthogonal). "Comments already stored are kept and stay readable" holds.
  3. The public-surface change in @objectstack/platform-objects — right. enable.feeds: false on four exported definitions, served through /meta/object. The key is valid and means what the PR says: ObjectCapabilities.feeds is z.boolean().default(true) on a strict object (object.zod.ts :302; opt-out contract :214–:226), precedent sys-comment-reaction.object.ts :138. No packages/spec change, no generated spec artefact owed, no governed path in the diff.
  4. The console consumer — right, read at the PIN. .objectui-sha is daeb77fc… on the head and on origin/main (the PR does not move it). At that sha RecordDetailView.tsx:1754 reads objectDef?.enable?.feeds !== false and :3284 prunes the Discussion nodes from the rendered page; activitiesEnabled is a separate read, so the activity timeline is untouched, as the changeset states. The PR cites 63d00da, a descendant of the pin carrying the same lines — fine, but the pin is the reading Console Pin Gate builds.
  5. No platform producer is broken — right. At the head no non-test code creates sys_comment outside plugin-audit's own hooks; no thread literal naming one of the four objects exists under packages/qa, examples, or in objectui's tests (objectui names sys_user only in activity-roster tests). The dogfood comment fixtures use their own cmt_* objects.
  6. The pins — right, and they pin the composition rather than the gate. identity-objects-feeds-off.test.ts imports the REAL four definitions through the already-registered @objectstack/platform-objects/identity → src alias (vitest.config.ts, the [security] The compliance ledger stores a JWT signing-key row's key material in its create snapshot, and an admin is served it through the ledger's by-id door while the key object itself declares no API door #21197 entry), boots a real ObjectQL, and installs the real installAuditWriters(engine, packageId) (:1124). Per object: code + status + object asserted and no row lands; grandfathered row: the gate is shown live on the same thread first, then the stored row reads back and a body edit saves; a CONTROL business object still accepts a comment. The file is in tsconfig.test.json's program (TypeScript Type Check green). The generic gate stays pinned in audit-writers.test.ts and capability-gate-update-verb.test.ts. The ablation table in the PR body is the dev's claim and was not re-run here; the CI-run pins are the verdict.
  7. The sys_comment.thread_id example swap — right. sys_user:abc123 → account:9001 in sys-comment.object.ts :10 and :129; the en bundle regenerated (AGENTS.md: en is rewritten from source), the zh-CN / ja-JP / es-ES leaf VALUES swapped by hand (permitted: editing a translated string is fine, no key added or dropped). git grep sys_user:abc123 at the head: 0 hits outside CHANGELOGs; none of the four drift-listed docs restates the example. The shipped example no longer prescribes a request this PR refuses.
  8. The code comments citing objectui#12614 item 1 in the four enable: blocks are code comments beside neighbours citing #1591 / #3543 — not runtime strings, not rule text. Not a defect.

Gate verdicts on 01f606f4b: all five required contexts success — Lint & Repo Gates, TypeScript Type Check, Test Core (and its six shards), Build Core, Governed Surface Queue Guard. Check Changeset success in both suites (the 10:24 run and the 11:20 re-run after the body edit, completed 11:22:15Z). Every skipped row is a path-filtered job, the matrix placeholder row or the opt-in tarball smoke; no failure and no in_progress remains on the head.

② Semver level

  • .changeset/23838-identity-feeds-off.md: @objectstack/platform-objects: minor, ! in the title, a BREAKING banner, the Clause-② line, and the adr-0087 HTML-comment marker not-required (no-migration-prescription).
  • Level — right. A narrowing is breaking; the launch-window convention ships breaking as minor and refuses major (check-changeset-no-major.mjs header, end condition at GA). patch or skip-changeset would each be wrong for this diff.
  • Package set — right; one prose gap, not blocking. @objectstack/plugin-audit also moves (a help-string example in a published object plus its bundles). Both packages sit in the one 72-package fixed group (.changeset/config.json), so plugin-audit versions with platform-objects regardless, and the LEVEL axis asks only that at least one moved package be graded minor or above (met). The body does not name the example swap; it changes one description's example and no behaviour, and the PR body's acceptance notes record it. Noted; not a condition of this verdict.
  • ADR-0087 disposition — right. The body carries no FROM → TO rewrite and no migration heading or table (the Remedy line is behavioural — stop creating comments there — not a code or metadata rewrite; the framing words inside the marker's own argument form no prescription shape), so the category's one mechanical refusal does not fire, and substantively nothing is for objectstack migrate meta to rewrite: no spec key, export, authorable spelling or stored shape moves, and stored rows are kept. Carried by Check Changeset (pr-automation.yml :967–:977), success.
  • Clause-②: — right. no (narrowing: the comment create door refuses on four platform objects that accept it today) on the PR body and in the changeset, byte-identical. clause2-line.mjs readArmToken (:286) reads the first token inside the parenthetical, and the : after it is neither a word character nor |, so the arm is narrowing (the docblock at :244–:248 says exactly this). no is truthful: no accept set widens. That arm is what makes this the narrowing face and this record one at CONTRACT_REVIEW_TIER.

③ Boundary flags

  • open_questions: [] in both os-dev-reports (6213309502, 6214361309). None owed.
  • Round-1 out_of_scope_findings (the thread_id example): answered — the seat's file-surface amendment 6213345119 added sys-comment.object.ts and the four bundles, the round-2 commits (941eb8a2e, 01f606f4b) carry the fix, and ①.7 verifies 0 survivors at the head.
  • Round-1 deviations: (a) a temporary --fresh backend on a random port, stopped by its recorded PID — within Multi-agent discipline §8; (b) harness-backgrounded gate batches, waited on — process only; (c) the model-free trailer pair — AGENTS.md wins, correct; (d) the definition-versus-surface conflict named rather than resolved silently — closed by the amendment; (e) objectui#12614 cited in code comments — accepted (①.8).
  • Round-2 deviations: (a) the PR-body sentence the dev left for the seat — written: the body's first acceptance-notes bullet now carries it (body updated 2026-10-16T11:20:40Z), so the body is current; (b) the worktree recreate/remove and (c) one typecheck lock queue-timeout retried and measured green — process notes, and CI's TypeScript Type Check is the verdict in any case; (d) trailers, as above.
  • File surface: the PR's 11 paths are exactly the amended claim surface (four enable: blocks, the pins file, the sys_comment object and its four bundles — both domain:services, declared per the amendment) plus the changeset. No breach.
  • Base drift: the head is not merged with the current origin/main (944f03850); GitHub reports it mergeable with no conflict, and the queue rebuilds on current main. Nothing owed before adoption.
  • Docs Drift Check (advisory): the four hand-written pages it lists name sys_comment only; none restates the changed example. No docs follow-up owed.
  • Reviewer's own footprint: the only script executed was scripts/pm/record-recognisers.mjs --template (and its --paths probe, which correctly deferred to the Clause-②: arm) — the record's shape, not a gate, build or test. Nothing was checked out, built or run.
  • Landing stays the owning seat's act after this record: the PR is a draft; ready first, arm second (§7).

Implemented-by: claude/issue-23838-identity-feeds-off
Reviewed-by: session_01TQLy3Yq6vF4SDpTXdr3Uwi

VERDICT: PASS

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

席位核对 · ✅ ACCEPT: PR #23869 at 01f606f4b8 · domain:engine seat 2 · session_01TQLy3Yq6vF4SDpTXdr3Uwi · 2026-10-16T11:34Z

Basis: claim 6211755973 and its file-surface amendment 6213345119 on #23838; the dev's reports 6213309502 and 6214361309; the contract review record 6214578176 (CONTRACT_REVIEW_TIER, narrowing face, PASS on this head); the seat's own reading of every non-test hunk against origin/main.

Contract review adoption. The record was produced by an isolated subagent and adopted after a tool-use audit of its transcript: 46 shell calls, all reads (git show, git fetch, GET on the REST API, the record template), and one write to its own scratch file. No GitHub write, checkout, build or test.

Checklist

  • Shape. Draft, base main, first line Fixes #23838; the other numbers in the body (objectui#12614, fix(platform-objects,metadata-core,service-messaging): Setup descriptions are plain admin sentences; ADR references move to the docblocks #23845) carry no closing verb. Clause-②: no (narrowing: …) is on its own line in the body and the changeset.
  • Scope. 11 paths, exactly the amended claim surface: the four enable: blocks (+3 lines each), the pins file, sys-comment.object.ts and its four bundles (the thread_id example, made false by this card and fixed in the patch round), and the changeset. The plugin-audit files are declared to domain:services (6211755973's amendment; [PM seat] domain:services · seat 2 — ⏳ vacant #21118 6213353522).
  • Behaviour. The narrowing is the metadata flag alone; the existing FEEDS_DISABLED gate in plugin-audit is untouched. The pins assert code + status + object through the real ObjectQL and the real installAuditWriters, plus the grandfathered-row case and a CONTROL; the dev's ablation legs each turned their pin red.
  • Changeset, sentence by sentence: the title; "a comment create on one of their records answers 403 FEEDS_DISABLED"; the record page drops the Discussion feed (objectui reads enable.feeds !== false, confirmed at the pin by the record); the data-API bullet (create refused, a re-thread refused the same way); the stored-comments bullet (kept, readable, a body edit saves); "Unchanged"; the remedy. minor with ! and the BREAKING banner, per the launch-window convention. The record's one note stands: the changeset does not name the thread_id example swap; plugin-audit versions with the fixed group regardless, and the PR body names it.
  • Gates on the head. ci-failure.mjs --pr 23869: GREEN, 40 of 40. Six skips, all on check-expected-skips.mjs's roster. The earlier red TypeScript Type Check / Lint & Repo Gates rows were on superseded heads (4e5399c4b, 941eb8a2e), where every member lane read cancelled.
  • Landing checks. check-governed-merges --pr 23869: NOT governed, 291 changed lines. git merge-tree against current origin/main (d0fe05048) is clean.

Out of scope: none left open. The round-1 finding was fixed in this PR; the four docs the drift check lists name sys_comment only.

Next: ready, then auto-merge through the queue.


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/m tests tooling

Projects

None yet

2 participants