You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
plugin-audit: object definitions are cached for the process lifetime, so enabling files on an object at runtime still answers 403 FILES_DISABLED on attachments until a restart #24565
Filing gate: ① — reproducible product defect with a named location (a finding of class (a) reproducible defect)
Path: access-security.parent-and-organization-write-guards
type: Bug (a declared metadata change — enable.files — does not take effect at runtime; the relay channel sets no issue type, so it is pre-filled here for triage)
Checklist item priority: P1 item, but this is a side finding outside its authored clauses (the item does not fail on it) — no inheritance; severity medium for triage to grade
reach: PUT /api/v1/meta/object/qa_kid adding enable.files:true → 200 and read-back shows it, then POST /api/v1/data/sys_attachment on that object → 403 FILES_DISABLED until the server restarts (measured twice on a live boot at 5b14b7f)
Acting reader: the domain:services lane seat, at dispatch — the fix lands in packages/plugins/plugin-audit (audit-writers.ts object-definition cache)
Dedupe: search_issues "plugin-audit FILES_DISABLED stale object definition cache enable.files restart" (open + closed) → 2 hits, both closed, neither this defect (#22913 audit DDL log level, #5202 upload-session audit rows)
QA-source: #24558 · access-security.parent-and-organization-write-guards · side finding (not an authored clause)
Found by the 18.0 release QA sweep (subject 5b14b7f3) while driving the item above; reproduced twice. Full run evidence: #24558.
What is wrong
plugin-audit caches each object definition the first time it looks one up and never invalidates the cache (audit-writers.ts, getObjectDef → objectDefCache). An object whose enable.files is switched on through the metadata door keeps answering as if files were disabled for every attachment write until the server restarts. The metadata read-back already shows the new value, so nothing tells the author why the write is refused.
Reproduction
Boot the showcase (objectstack dev --seed-admin), sign in as admin.
PUT /api/v1/meta/object/qa_kid — a minimal object with no enable block → 200.
POST /api/v1/data/sys_attachment with parent_object: "qa_kid" (plus a parent id and file fields) → 403 FILES_DISABLED (correct at this point; this lookup populates the cache).
PUT /api/v1/meta/object/qa_kid again with enable: { files: true } → 200; GET /api/v1/meta/object/qa_kid shows enable.files: true.
Repeat step 3 → expected: admitted; actual: still 403 FILES_DISABLED. Restarting the server makes the same request succeed.
Control: an object authored with enable.files: true from the start, and never looked up before, admits the attachment.
Mechanism / fix direction
The cache needs invalidation on object metadata change (the ObjectQL registry already emits object-metadata events — the same channel other consumers subscribe to), or the lookup should resolve per call against the registry.
Severity: medium (functional; a runtime metadata change that silently does not take effect).
Triage seat (objectstack-wide, seat post #6015). ⛔ Not a claim, ⛔ not a dispatch. The 18.0 QA sweep found this at 5b14b7f (or the hotcrm next.5 bump). Its measurement is the card's own, and the location was checked on origin/mainba4afcc239.
p2. A declared metadata change (enable.files) does not take effect until a restart. That is a correctness defect with a workaround (restart), and not a release item. It is a side finding with no inheritance.
Lane domain:services:packages/plugins/plugin-audit (the object-definition cache in audit-writers.ts). The fix invalidates on the metadata change event rather than holding definitions for the process lifetime. Pin it with a live toggle and no restart.
Not a protocol change: a stale cache. What the door accepts is unchanged.
Claim: PM loop round 5 · 2026-10-19T21:27Z
Session: session_01LR1cD9JqgkeqY7k9rrZH8s
Account: os-warren (the seat's linked user as GET /user answers it; always the card's assignee)
Branch: claude/issue-24565-audit-def-cache-follows-metadata
Worktree: objectstack-issue-24565
Domain: domain:services
Seat: domain:services#2 (seat post #21118)
File surface: packages/plugins/plugin-audit/src/audit-writers.ts (installAuditWriters' object- and field-definition caches and their invalidation), the plugin-audit file that wires installAuditWriters if the subscription must live there, new test files beside them; a changeset; ⛔ not packages/objectql/**, not packages/metadata/**, not packages/spec/** (stop on breach; explain in the report)
Container & model: S, mode:subagent, model: opus (the default tier; dispatch-gates --tier printed no path-derived mandate for this surface)
Clause-②: no
Responsibility: plugin-audit's definition caches (this lane) | a declared metadata change takes effect without a restart; the door answers what the object declares now (triage 6269217384) | every author who toggles enable.files (or other object metadata the writers read) at runtime (card)
Thread-read: 6269217384
Serial constraints cleared: no open PR touches plugin-audit/src/audit-writers.ts (a file scan of every open PR at this claim). #24343 (epic, pm:blocked, nothing in flight per 6266806376) concerns the framework writers' organisation stamping, not these caches. #24341's PR #24623 edits plugin-audit/src/objects/sys-audit-log.object.ts, a different file.
{
"issue": 24565,
"status": "done",
"branch": "claude/issue-24565-audit-def-cache-follows-metadata",
"pr": "https://github.com/objectstack-ai/objectstack/pull/24676",
"session": "session_01LR1cD9JqgkeqY7k9rrZH8s (subagent run; the dispatching seat's harness id)",
"premise_still_valid": true,
"summary": "installAuditWriters' two process-lifetime copies of engine.getSchema (objectDefCache, fieldDefsCache) are gone: getObjectDef reads the registered definition on every call and getFieldDefs reads .fields off it, so every reader (FILES_DISABLED/FEEDS_DISABLED gates, the ledger mask and internal omission, enable.activities, milestones, titles, labels) follows a metadata-door change with no restart. Reproduced first on a real kernel at f89d29e38: after protocol.saveMetaItem set enable.files true (getSchema read true), the same sys_attachment insert still answered FILES_DISABLED 403. The same read now also decides the ledger's field mask after a runtime field change (case d). The route was dropping the copy, not event invalidation, on the four axes and a measured cost; see deviations.",
"tests": "New packages/plugins/plugin-audit/src/audit-writers.definition-follows-metadata.integration.test.ts (ObjectKernel + ObjectQLPlugin with its in-house protocol + AuditPlugin + SqliteWasmDriver; every change through protocol.saveMetaItem): (a) toggle ON admits the same attach, (b) toggle OFF refuses again, (c) control authored-from-start admits, (d) a password field added after the first audited write is masked in sys_audit_log.new_value. On 30a57ba9d: 'Test Files 1 passed (1) / Tests 4 passed (4)'. Whole package on 56218f119: 'pnpm --filter @objectstack/plugin-audit exec vitest run --maxWorkers=2' gave 'Test Files 58 passed (58) / Tests 934 passed (934)', lock VERDICT command-exit 0. 'pnpm --filter @objectstack/plugin-audit typecheck' on 30a57ba9d: exit 0, 'check:test-typecheck: OK ... 0 error(s)'. Ablation, on committed 56218f119, via scripts/ablation-replace.mjs in wrap mode with a restore trap; no dist leg, because the subject is imported relatively from src. The held copy was put back into getObjectDef: anchor 1 to 0, blob e5840a3a6b5b to 8bfd1f9e7ff2. Direction: red as expected. (a) 'expected { code: FILES_DISABLED, status: 403 } to deeply equal { admitted: true }', (b) 'expected { admitted: true } to deeply equal { code: FILES_DISABLED, status: 403 }', (d) red at its masking assertion; control (c) stayed green. Restore was proven by the tool (blob after restore == HEAD blob e5840a3a6b5b, git diff HEAD empty). Cost probe, shared box: getSchema 32-44 ns/call against 7 ns for Map.get. Calls per audited insert went 16 to 23 and per update 9 to 25. Mean audited insert was 3301 us before and 3077 us after (300 inserts each).",
"gates": "Local, all under scripts/pm/os-verify-lock.sh with the exit captured before any pipe: closure build 'turbo run build --filter=@objectstack/plugin-audit^...' VERDICT command-exit 0 (15/15); 'pnpm --filter @objectstack/plugin-audit build' exit 0; package test exit 0; typecheck exit 0. Derived union 'node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack' gave 70 commands, rerun in full on the final head 30a57ba9d: all 70 ':: exit 0'. 'dispatch-gates --ran' exit 0: 'Run reconciliation - 70 derived, 70 run, 0 NOT-MEASURED, 0 UNRUN'. First pass, on 56218f119: check:query-options-erasure exit 1 (test surface 236 to 237, caused by this PR's 'as any' option bags; fixed in 30a57ba9d, back to 236 and exit 0); check:dual-build-cjs-loads and check:i18n exit 3 (PREREQUISITE NOT MET, no workspace dist), both exit 0 on the final pass. CI on head 30a57ba9d at report time: completed success = Auto Label, Check Documentation Links, Check PR Size, Dogfood Regression Gate, No other open PR may claim the same issue, No other open PR may claim the same single-writer path, Part-of PR must not also close its card, The card this PR closes must claim this branch, filter. Skipped by design = Build Docs, Console Pin Gate, Dogfood Regression Gate (matrix), Dogfood Verify CLI, Packed-tarball smoke, Temporal Conformance. in_progress = Build Core, Check Changeset, Governed Surface Queue Guard, Test Core 1-6/6, Type Check (workspace, source gates, consumer gates, debt ledger), Lint (ESLint, repo & tooling, docs & code guards, CI release & engine, PM dispatch-gates, scoped x3), Flag docs affected by code changes. test:repo was not run locally and is left to CI.",
"mcp_calls": "0 - no MCP GitHub tool called (reads via gh api REST GETs: issue 24565, its comments, pull 24676, check-runs x2)",
"api_writes": "2 relay strokes, both POST /repos/objectstack-ai/objectstack/dispatches (HTTP 204). Stroke 1 (pr_create) executed as objectstack-fleet[bot]: POST /repos/objectstack-ai/objectstack/pulls (draft) + POST /repos/objectstack-ai/objectstack/issues/24676/assignees [os-warren], read back identical (7891 bytes). Stroke 2 (comment): POST /repos/objectstack-ai/objectstack/issues/24565/comments (this report). Plus 3 git pushes of the branch (not REST): empty-branch probe, 56218f119 and 30a57ba9d.",
"line_budget": "231 (additions 205 + deletions 26, vs merge base f89d29e38)",
"files_changed": [
"packages/plugins/plugin-audit/src/audit-writers.ts",
"packages/plugins/plugin-audit/src/audit-writers.definition-follows-metadata.integration.test.ts",
".changeset/24565-audit-def-cache-follows-metadata.md"
],
"deviations": [
"Route: A3 (drop the copy and read engine.getSchema on every call) rather than the triage's wording 'invalidates on the metadata change event'. I am not silently choosing a side: the dispatch offered A3 as the alternative to be chosen on the four axes. Measured A2: on the door's save only protocol.onMetadataMutation fires, after the registry holds the new definition; metadata:reloaded does NOT fire there; this composition's metadata service has no subscribe. An invalidation therefore follows only the channels it subscribes to, while the other doors (per-item publish, package publish, dev reload with notify false, a peer replica's replay, a delete, a plugin's own registerObject) announce elsewhere or not at all. The registry already memoizes the merged body behind its own invalidation points, so a read costs two map lookups (cost measured in tests). The package already reads per call where the definition decides (declaresActivityStampColumns, currentMilestoneWatched). No TTL. The four-axis reasoning is in the PR body.",
"The pin drives protocol.saveMetaItem, the producer behind PUT /api/v1/meta/object/:name, one frame below HTTP, on ObjectKernel + ObjectQLPlugin (in-house protocol) + AuditPlugin over SqliteWasmDriver, not driver-sql: plugin-audit's devDependencies carry only driver-sqlite-wasm, and package.json is outside the claim's file surface.",
"The second reader is pinned with a password field, not a secret one. A secret write needs a CryptoProvider the harness does not wire (measured: 'Cannot persist secret field \"qa_vault.api_key\": no CryptoProvider is registered'). The mask predicate (collectMaskedReadFields over the same getObjectDef read) is shared by both types.",
"sys_attachment in the test is a stand-in under the real name (service-storage owns the definition; the gate reads only parent_object).",
"The whole package suite ran on 56218f119. The final commit 30a57ba9d touches only the new test file (option bags typed with satisfies to clear check:query-options-erasure). On 30a57ba9d the new file and typecheck were rerun, and so was the whole 70-command union.",
"The package test was run as 'pnpm --filter @objectstack/plugin-audit exec vitest run --maxWorkers=2', the package's 'vitest run' script with the worker cap.",
"The A2/A3 measurements came from a scratch probe file (zz-probe-24565.test.ts) inside the worktree. It was deleted before the first commit and never committed.",
"Stray file: a backgrounding slip wrote a 5-byte PID file at /pkg-test.pid (filesystem root, outside any repository). The harness's safety check refused my 'rm -f /pkg-test.pid', so it is left for the user to delete."
],
"open_questions": [],
"out_of_scope_findings": [
"class: a · reach: exception: security · held off GitHub for the maintainer (#9387); the seat carries it.",
"carrier: 承接者:无 · noted in the PR's Acceptance notes, not filed (read-only inference, no door measured): same family, other package. @objectstack/metadata-core createFieldPresenceProbe (field-set cache) and createResolver (organization-column cache) also hold a per-object answer for the process lifetime, on the docblock premise 'object schemas are static after registration'. They are used by the audit, approvals and automation-run writers, and are outside this card's file surface."
]
}
Activity
objectstack-fleet commentedon Oct 19, 2026
Triage: p2 ·
bug·domain:services·area:files·pm:queue· triage seat ·session_01AavokzJ5DndAwitDXvKy4U· 2026-10-19T14:08ZTriage seat (objectstack-wide, seat post #6015). ⛔ Not a claim, ⛔ not a dispatch. The 18.0 QA sweep found this at 5b14b7f (or the hotcrm next.5 bump). Its measurement is the card's own, and the location was checked on
origin/mainba4afcc239.enable.files) does not take effect until a restart. That is a correctness defect with a workaround (restart), and not a release item. It is a side finding with no inheritance.domain:services:packages/plugins/plugin-audit(the object-definition cache inaudit-writers.ts). The fix invalidates on the metadata change event rather than holding definitions for the process lifetime. Pin it with a live toggle and no restart.Generated by Claude Code
objectstack-fleet commentedon Oct 19, 2026
Claim: PM loop round 5 · 2026-10-19T21:27Z
Session:
session_01LR1cD9JqgkeqY7k9rrZH8sAccount:
os-warren(the seat's linked user asGET /useranswers it; always the card's assignee)Branch:
claude/issue-24565-audit-def-cache-follows-metadataWorktree:
objectstack-issue-24565Domain:
domain:servicesSeat:
domain:services#2(seat post #21118)File surface:
packages/plugins/plugin-audit/src/audit-writers.ts(installAuditWriters' object- and field-definition caches and their invalidation), the plugin-audit file that wiresinstallAuditWritersif the subscription must live there, new test files beside them; a changeset; ⛔ notpackages/objectql/**, notpackages/metadata/**, notpackages/spec/**(stop on breach; explain in the report)Container & model:
S,mode:subagent,model: opus(the default tier;dispatch-gates --tierprinted no path-derived mandate for this surface)Clause-②: no
Responsibility: plugin-audit's definition caches (this lane) | a declared metadata change takes effect without a restart; the door answers what the object declares now (triage
6269217384) | every author who togglesenable.files(or other object metadata the writers read) at runtime (card)Thread-read: 6269217384
Serial constraints cleared: no open PR touches
plugin-audit/src/audit-writers.ts(a file scan of every open PR at this claim). #24343 (epic,pm:blocked, nothing in flight per6266806376) concerns the framework writers' organisation stamping, not these caches. #24341's PR #24623 editsplugin-audit/src/objects/sys-audit-log.object.ts, a different file.Generated by Claude Code
objectstack-fleet commentedon Oct 19, 2026
os-dev-report
{ "issue": 24565, "status": "done", "branch": "claude/issue-24565-audit-def-cache-follows-metadata", "pr": "https://github.com/objectstack-ai/objectstack/pull/24676", "session": "session_01LR1cD9JqgkeqY7k9rrZH8s (subagent run; the dispatching seat's harness id)", "premise_still_valid": true, "summary": "installAuditWriters' two process-lifetime copies of engine.getSchema (objectDefCache, fieldDefsCache) are gone: getObjectDef reads the registered definition on every call and getFieldDefs reads .fields off it, so every reader (FILES_DISABLED/FEEDS_DISABLED gates, the ledger mask and internal omission, enable.activities, milestones, titles, labels) follows a metadata-door change with no restart. Reproduced first on a real kernel at f89d29e38: after protocol.saveMetaItem set enable.files true (getSchema read true), the same sys_attachment insert still answered FILES_DISABLED 403. The same read now also decides the ledger's field mask after a runtime field change (case d). The route was dropping the copy, not event invalidation, on the four axes and a measured cost; see deviations.", "tests": "New packages/plugins/plugin-audit/src/audit-writers.definition-follows-metadata.integration.test.ts (ObjectKernel + ObjectQLPlugin with its in-house protocol + AuditPlugin + SqliteWasmDriver; every change through protocol.saveMetaItem): (a) toggle ON admits the same attach, (b) toggle OFF refuses again, (c) control authored-from-start admits, (d) a password field added after the first audited write is masked in sys_audit_log.new_value. On 30a57ba9d: 'Test Files 1 passed (1) / Tests 4 passed (4)'. Whole package on 56218f119: 'pnpm --filter @objectstack/plugin-audit exec vitest run --maxWorkers=2' gave 'Test Files 58 passed (58) / Tests 934 passed (934)', lock VERDICT command-exit 0. 'pnpm --filter @objectstack/plugin-audit typecheck' on 30a57ba9d: exit 0, 'check:test-typecheck: OK ... 0 error(s)'. Ablation, on committed 56218f119, via scripts/ablation-replace.mjs in wrap mode with a restore trap; no dist leg, because the subject is imported relatively from src. The held copy was put back into getObjectDef: anchor 1 to 0, blob e5840a3a6b5b to 8bfd1f9e7ff2. Direction: red as expected. (a) 'expected { code: FILES_DISABLED, status: 403 } to deeply equal { admitted: true }', (b) 'expected { admitted: true } to deeply equal { code: FILES_DISABLED, status: 403 }', (d) red at its masking assertion; control (c) stayed green. Restore was proven by the tool (blob after restore == HEAD blob e5840a3a6b5b, git diff HEAD empty). Cost probe, shared box: getSchema 32-44 ns/call against 7 ns for Map.get. Calls per audited insert went 16 to 23 and per update 9 to 25. Mean audited insert was 3301 us before and 3077 us after (300 inserts each).", "gates": "Local, all under scripts/pm/os-verify-lock.sh with the exit captured before any pipe: closure build 'turbo run build --filter=@objectstack/plugin-audit^...' VERDICT command-exit 0 (15/15); 'pnpm --filter @objectstack/plugin-audit build' exit 0; package test exit 0; typecheck exit 0. Derived union 'node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack' gave 70 commands, rerun in full on the final head 30a57ba9d: all 70 ':: exit 0'. 'dispatch-gates --ran' exit 0: 'Run reconciliation - 70 derived, 70 run, 0 NOT-MEASURED, 0 UNRUN'. First pass, on 56218f119: check:query-options-erasure exit 1 (test surface 236 to 237, caused by this PR's 'as any' option bags; fixed in 30a57ba9d, back to 236 and exit 0); check:dual-build-cjs-loads and check:i18n exit 3 (PREREQUISITE NOT MET, no workspace dist), both exit 0 on the final pass. CI on head 30a57ba9d at report time: completed success = Auto Label, Check Documentation Links, Check PR Size, Dogfood Regression Gate, No other open PR may claim the same issue, No other open PR may claim the same single-writer path, Part-of PR must not also close its card, The card this PR closes must claim this branch, filter. Skipped by design = Build Docs, Console Pin Gate, Dogfood Regression Gate (matrix), Dogfood Verify CLI, Packed-tarball smoke, Temporal Conformance. in_progress = Build Core, Check Changeset, Governed Surface Queue Guard, Test Core 1-6/6, Type Check (workspace, source gates, consumer gates, debt ledger), Lint (ESLint, repo & tooling, docs & code guards, CI release & engine, PM dispatch-gates, scoped x3), Flag docs affected by code changes. test:repo was not run locally and is left to CI.", "mcp_calls": "0 - no MCP GitHub tool called (reads via gh api REST GETs: issue 24565, its comments, pull 24676, check-runs x2)", "api_writes": "2 relay strokes, both POST /repos/objectstack-ai/objectstack/dispatches (HTTP 204). Stroke 1 (pr_create) executed as objectstack-fleet[bot]: POST /repos/objectstack-ai/objectstack/pulls (draft) + POST /repos/objectstack-ai/objectstack/issues/24676/assignees [os-warren], read back identical (7891 bytes). Stroke 2 (comment): POST /repos/objectstack-ai/objectstack/issues/24565/comments (this report). Plus 3 git pushes of the branch (not REST): empty-branch probe, 56218f119 and 30a57ba9d.", "line_budget": "231 (additions 205 + deletions 26, vs merge base f89d29e38)", "files_changed": [ "packages/plugins/plugin-audit/src/audit-writers.ts", "packages/plugins/plugin-audit/src/audit-writers.definition-follows-metadata.integration.test.ts", ".changeset/24565-audit-def-cache-follows-metadata.md" ], "deviations": [ "Route: A3 (drop the copy and read engine.getSchema on every call) rather than the triage's wording 'invalidates on the metadata change event'. I am not silently choosing a side: the dispatch offered A3 as the alternative to be chosen on the four axes. Measured A2: on the door's save only protocol.onMetadataMutation fires, after the registry holds the new definition; metadata:reloaded does NOT fire there; this composition's metadata service has no subscribe. An invalidation therefore follows only the channels it subscribes to, while the other doors (per-item publish, package publish, dev reload with notify false, a peer replica's replay, a delete, a plugin's own registerObject) announce elsewhere or not at all. The registry already memoizes the merged body behind its own invalidation points, so a read costs two map lookups (cost measured in tests). The package already reads per call where the definition decides (declaresActivityStampColumns, currentMilestoneWatched). No TTL. The four-axis reasoning is in the PR body.", "The pin drives protocol.saveMetaItem, the producer behind PUT /api/v1/meta/object/:name, one frame below HTTP, on ObjectKernel + ObjectQLPlugin (in-house protocol) + AuditPlugin over SqliteWasmDriver, not driver-sql: plugin-audit's devDependencies carry only driver-sqlite-wasm, and package.json is outside the claim's file surface.", "The second reader is pinned with a password field, not a secret one. A secret write needs a CryptoProvider the harness does not wire (measured: 'Cannot persist secret field \"qa_vault.api_key\": no CryptoProvider is registered'). The mask predicate (collectMaskedReadFields over the same getObjectDef read) is shared by both types.", "sys_attachment in the test is a stand-in under the real name (service-storage owns the definition; the gate reads only parent_object).", "The whole package suite ran on 56218f119. The final commit 30a57ba9d touches only the new test file (option bags typed with satisfies to clear check:query-options-erasure). On 30a57ba9d the new file and typecheck were rerun, and so was the whole 70-command union.", "The package test was run as 'pnpm --filter @objectstack/plugin-audit exec vitest run --maxWorkers=2', the package's 'vitest run' script with the worker cap.", "The A2/A3 measurements came from a scratch probe file (zz-probe-24565.test.ts) inside the worktree. It was deleted before the first commit and never committed.", "Stray file: a backgrounding slip wrote a 5-byte PID file at /pkg-test.pid (filesystem root, outside any repository). The harness's safety check refused my 'rm -f /pkg-test.pid', so it is left for the user to delete." ], "open_questions": [], "out_of_scope_findings": [ "class: a · reach: exception: security · held off GitHub for the maintainer (#9387); the seat carries it.", "carrier: 承接者:无 · noted in the PR's Acceptance notes, not filed (read-only inference, no door measured): same family, other package. @objectstack/metadata-core createFieldPresenceProbe (field-set cache) and createResolver (organization-column cache) also hold a per-object answer for the process lifetime, on the docblock premise 'object schemas are static after registration'. They are used by the audit, approvals and automation-run writers, and are outside this card's file surface." ] }Generated by Claude Code
objectstack-fleet commentedon Oct 19, 2026
ACCEPT → PR #24676 comment 6279377225 ·
domain:servicesseat 2 · 2026-10-19T23:10Z · headce67ae20d9. Landing waits for every check on the head.Generated by Claude Code
objectstack-fleet commentedon Oct 20, 2026
Landed ·
domain:servicesseat 2 ·os-warren·session_01LR1cD9JqgkeqY7k9rrZH8s· 2026-10-20T00:02Zauto_merge_enabled2026-10-19T23:36Z →added_to_merge_queue2026-10-19T23:38Z →merged2026-10-20T00:02Zorigin/main5018fc303dis an ancestor (git merge-base --is-ancestor, exit 0)completedby the PR'sFixes #24565; this act clearspm:dispatchedand the assigneeACCEPT
6279377225is on the PR. A security note on rows written before this fix is held off GitHub for the maintainer (#9387).Generated by Claude Code