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-sharing: the #8418 phantom-anchor write-deny diagnostic goes silent on a federated object that maps owner_id through external.columnMap over a plugin driver that ignores the map (epic #27261) #27662
epic:#27261#1 · marchtian · session_017ihL2c5z3q4h8inrn5kwqV
Filing gate: ① operator-diagnostic regression owed by landed work (#27425, PR #27476f57eddcf), from the post-landing contract review 6493803142 (④ should-fix 3) and the seat carry 6493297056.
Reader: the epic PM (#27261) dispatches it in the epic subtree; the fix is in packages/plugins/plugin-sharing/src/ (notePhantomAnchorWriteDeny and its caller).
Dedupe (open AND closed): "phantom anchor write-deny diagnostic notePhantomAnchorWriteDeny columnMap map-ignoring plugin driver" → 0 hits.
reach: read on main, not measured live. notePhantomAnchorWriteDeny (#8418) keys on hasPhantomOwnerAnchor, which answers false since #27425 when external.columnMap maps a remote column onto owner_id. A plugin driver does not apply columnMap, so its rows carry no owner_id; every member write is refused (fail closed, correct), but the one-line server log that tells the operator why no longer fires. security-external-owner-unmapped still warns at author time.
type: Bug
epic:#27261#1 · marchtian · session_017ihL2c5z3q4h8inrn5kwqV
Claim: PM loop round 7 2026-10-29T21:52Z
Session: session_017ihL2c5z3q4h8inrn5kwqV (epic PM); implementing card thread session_017ihL2eGmV67aXQuY2TJg7s
Account: marchtian
Branch: claude/project-thread-be7tr8 (the card thread's platform-assigned branch — measured platform exception to claude/issue-<n>-<slug>)
Worktree: objectstack-issue-27662
Domain: domain:server
Seat: epic:#27261#1 (epic PM; no domain:* seat). Maintainer order, 田騏 2026-10-29T21:50Z: 「给我解释后续还有哪些卡,以及为什么不派」 (epic subtree p3 cards are dispatched, not left by pull)
File surface: packages/plugins/plugin-sharing/src/** (notePhantomAnchorWriteDeny, its caller, tests), .changeset/** (stop on breach; explain in the report)
Container & model: S, mode:thread, model: default tier (dispatch-gates --tier: no path-derived mandate), effort: high
Clause-②: no
Metadata-protocol: none
Responsibility: #27425 (PR #27476) counted a columnMap entry onto owner_id as proven, which took the mapped class out of the #8418 diagnostic's trigger
Thread-read: none
Premise: holds — on origin/mainnotePhantomAnchorWriteDeny keys on hasPhantomOwnerAnchor, which answers false when external.columnMap maps onto owner_id.
Serial constraints: #27661 (card thread) touches plugin-sharing's mapsRemoteColumnOntoOwner / federated-phantom-anchors.ts; keep this card's edits out of that predicate and say in the report if they overlap.
{
"issue": 27662,
"status": "done",
"branch": "claude/project-thread-be7tr8",
"pr": "https://github.com/objectstack-ai/objectstack/pull/27760",
"session": "session_017ihL2eGmV67aXQuY2TJg7s",
"premise_still_valid": true,
"summary": "matchesOwnerScope now hands the pre-image row it already read to notePhantomAnchorWriteDeny. The phantom-anchor branch is unchanged; a second branch logs the new exported UNSERVED_OWNER_WRITE_DENY_NOTICE, once per object under the same latch and with the same payload, when a federated object that is not phantom-anchored returns a row with no owner_id key (a plugin driver that ignores external.columnMap). A served NULL owner, a missing record and a declared-owner control stay silent; no verdict moves. Overlap with #27661: none. federated-phantom-anchors.ts is untouched; the new branch imports the already-exported isFederatedObject and reads no columnMap itself, so it adds no reader to the set #27661 consolidates. Deliberate width, named in the PR Acceptance notes: a federated object that DECLARES owner_id whose driver omits the key also gets the line (same operator fault; message says maps or declares).",
"tests": "head 41cbab7c (origin/main 34dc09b6 merged). Under os-verify-lock at 9ea80c51: pnpm --filter @objectstack/plugin-sharing test: Test Files 58 passed (58), Tests 1296 passed (1296); pnpm --filter @objectstack/plugin-sharing typecheck: exit 0 (tsc, tsconfig.scripts.json, check:test-typecheck OK 3 pinned signatures held). The merge brought no plugin-sharing change (git diff 481ade61 origin/main -- packages/plugins/plugin-sharing is empty). New [#27662] block: 6 cases. Ablation 1 (scripts/ablation-replace.mjs, src import path, no dist): replace 'notice = UNSERVED_OWNER_WRITE_DENY_NOTICE;' with 'return;', anchor 1 to 0, blob 558afc3b to 8991301f: 3 failed / 54 passed (the three firing cases); restored blob == HEAD, git diff HEAD empty. Ablation 2: replace the key-absent test 'row !== undefined && row[OWNER_FIELD] === undefined' with a constant true, blob 558afc3b to 9793f83b: 1 failed / 56 passed (the map-applying silent case, served NULL owner); restored blob == HEAD. A first attempt at ablation 2 was refused by the tool as a no-op (replacement was a substring of the anchor) and measured nothing.",
"gates": "dispatch-gates --commands at 41cbab7c derived 61; all 61 run locally with exit codes recorded before any pipe; --ran: 61 derived, 61 run, 0 NOT-MEASURED, 0 UNRUN (a DERIVED zero). check:dual-build-cjs-loads and check:i18n first exited 3 (no dist); rerun after check:type-check-debt built packages: both exit 0. PR check-runs on 41cbab7c at report time: 33 success, 13 skipped, 0 failure, 1 in_progress (Test Core (4/8)).",
"dogfood_battery": "n/a — no ! in the PR title and Clause-② is no without a (narrowing) arm",
"mcp_calls": "0",
"api_writes": "2 — relay pr_create (run 40966621624, PR #27760, body read back identical, assignees none); relay comment on #27662 (this report). git push of the branch is not a REST write.",
"open_questions": [],
"out_of_scope_findings": []
}
PR #27760 merged through the queue as 64599ec57481e6c15bac541dc3dddcff53282bfe (head 41cbab7c, seat ACCEPT 6510421573). A refused member write on a federated object whose mapped or declared owner column the driver did not serve logs UNSERVED_OWNER_WRITE_DENY_NOTICE again, at most once per object. The verdict is unchanged.
Activity
objectstack-fleet commentedon Oct 29, 2026
epic:#27261#1 · marchtian · session_017ihL2c5z3q4h8inrn5kwqV
Claim: PM loop round 7 2026-10-29T21:52Z
Session:
session_017ihL2c5z3q4h8inrn5kwqV(epic PM); implementing card threadsession_017ihL2eGmV67aXQuY2TJg7sAccount:
marchtianBranch:
claude/project-thread-be7tr8(the card thread's platform-assigned branch — measured platform exception toclaude/issue-<n>-<slug>)Worktree:
objectstack-issue-27662Domain:
domain:serverSeat:
epic:#27261#1(epic PM; nodomain:*seat). Maintainer order, 田騏 2026-10-29T21:50Z: 「给我解释后续还有哪些卡,以及为什么不派」 (epic subtree p3 cards are dispatched, not left by pull)File surface:
packages/plugins/plugin-sharing/src/**(notePhantomAnchorWriteDeny, its caller, tests),.changeset/**(stop on breach; explain in the report)Container & model:
S,mode:thread,model: default tier (dispatch-gates --tier: no path-derived mandate),effort: highClause-②: no
Metadata-protocol: none
Responsibility: #27425 (PR #27476) counted a
columnMapentry ontoowner_idas proven, which took the mapped class out of the #8418 diagnostic's triggerThread-read: none
Premise: holds — on
origin/mainnotePhantomAnchorWriteDenykeys onhasPhantomOwnerAnchor, which answers false whenexternal.columnMapmaps ontoowner_id.Serial constraints: #27661 (card thread) touches plugin-sharing's
mapsRemoteColumnOntoOwner/federated-phantom-anchors.ts; keep this card's edits out of that predicate and say in the report if they overlap.objectstack-fleet commentedon Oct 29, 2026
epic:#27261#1 · marchtian · session_017ihL2eGmV67aXQuY2TJg7s
os-dev-report
{ "issue": 27662, "status": "done", "branch": "claude/project-thread-be7tr8", "pr": "https://github.com/objectstack-ai/objectstack/pull/27760", "session": "session_017ihL2eGmV67aXQuY2TJg7s", "premise_still_valid": true, "summary": "matchesOwnerScope now hands the pre-image row it already read to notePhantomAnchorWriteDeny. The phantom-anchor branch is unchanged; a second branch logs the new exported UNSERVED_OWNER_WRITE_DENY_NOTICE, once per object under the same latch and with the same payload, when a federated object that is not phantom-anchored returns a row with no owner_id key (a plugin driver that ignores external.columnMap). A served NULL owner, a missing record and a declared-owner control stay silent; no verdict moves. Overlap with #27661: none. federated-phantom-anchors.ts is untouched; the new branch imports the already-exported isFederatedObject and reads no columnMap itself, so it adds no reader to the set #27661 consolidates. Deliberate width, named in the PR Acceptance notes: a federated object that DECLARES owner_id whose driver omits the key also gets the line (same operator fault; message says maps or declares).", "tests": "head 41cbab7c (origin/main 34dc09b6 merged). Under os-verify-lock at 9ea80c51: pnpm --filter @objectstack/plugin-sharing test: Test Files 58 passed (58), Tests 1296 passed (1296); pnpm --filter @objectstack/plugin-sharing typecheck: exit 0 (tsc, tsconfig.scripts.json, check:test-typecheck OK 3 pinned signatures held). The merge brought no plugin-sharing change (git diff 481ade61 origin/main -- packages/plugins/plugin-sharing is empty). New [#27662] block: 6 cases. Ablation 1 (scripts/ablation-replace.mjs, src import path, no dist): replace 'notice = UNSERVED_OWNER_WRITE_DENY_NOTICE;' with 'return;', anchor 1 to 0, blob 558afc3b to 8991301f: 3 failed / 54 passed (the three firing cases); restored blob == HEAD, git diff HEAD empty. Ablation 2: replace the key-absent test 'row !== undefined && row[OWNER_FIELD] === undefined' with a constant true, blob 558afc3b to 9793f83b: 1 failed / 56 passed (the map-applying silent case, served NULL owner); restored blob == HEAD. A first attempt at ablation 2 was refused by the tool as a no-op (replacement was a substring of the anchor) and measured nothing.", "gates": "dispatch-gates --commands at 41cbab7c derived 61; all 61 run locally with exit codes recorded before any pipe; --ran: 61 derived, 61 run, 0 NOT-MEASURED, 0 UNRUN (a DERIVED zero). check:dual-build-cjs-loads and check:i18n first exited 3 (no dist); rerun after check:type-check-debt built packages: both exit 0. PR check-runs on 41cbab7c at report time: 33 success, 13 skipped, 0 failure, 1 in_progress (Test Core (4/8)).", "dogfood_battery": "n/a — no ! in the PR title and Clause-② is no without a (narrowing) arm", "mcp_calls": "0", "api_writes": "2 — relay pr_create (run 40966621624, PR #27760, body read back identical, assignees none); relay comment on #27662 (this report). git push of the branch is not a REST write.", "open_questions": [], "out_of_scope_findings": [] }objectstack-fleet commentedon Oct 29, 2026
epic:#27261#1 · marchtian · session_017ihL2c5z3q4h8inrn5kwqV
Landed · 2026-10-29T23:26Z
PR #27760 merged through the queue as
64599ec57481e6c15bac541dc3dddcff53282bfe(head41cbab7c, seat ACCEPT 6510421573). A refused member write on a federated object whose mapped or declared owner column the driver did not serve logsUNSERVED_OWNER_WRITE_DENY_NOTICEagain, at most once per object. The verdict is unchanged.