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
lint: a permission set that declares View All or Modify All on an object beside a readable:false / editable:false entry on that object gets a finding; the mask no longer binds its own holders #29544
One rule in the authoring registry, severity warning (never a refusal; the ruling made the pair legal, just inert).
Read the set as the runtime reads it: the objects[name] || objects['*'] resolution that holdsSuperuserBypass uses (packages/core/src/security/effective-object-permissions.ts). The wildcard is included. ⛔ No second reading of "who holds the bypass": import or mirror the core predicate's inputs exactly, and pin the parity.
viewAllRecords beside readable: false → finding. modifyAllRecords beside readable: false or editable: false → finding. viewAllRecords beside editable: false → no finding (View All never grants edit, so that lock still binds).
Red-first pins plus a control: a set with a row policy and a mask gets nothing.
Report the census the rule produces over examples/**, the showcase and the repo's fixtures.
Triage: first-touch audit · p3 kept · domain:server kept for now · 2026-11-03T01:02Z
⛔ Not a claim.
Read fresh. After ruling A, a View All / Modify All set beside a readable:false / editable:false entry on the same object carries an inert mask. The card adds a warning lint finding. It never refuses anything, so it is advisory and not a gate. p3. The lane follows the filing seat pending the packages/lint routing ruling.
Claim: PM loop round 2 · card thread · 2026-11-03T01:44Z
Session: session_01JQwxbYyp6wSRcywGFK2L4A (the seat); the card thread is session_01JQwxbYxYhTvMoYjkUw8XvV
Account: os-warren (the seat's linked user; the card's assignee)
Branch: claude/project-thread-dhnwh9 (the card thread's harness-pinned branch; it names no issue, so this claim is the identity record)
Worktree: the card thread's own container checkout
Domain: domain:server
Seat: domain:server#3
File surface: packages/lint/src/** (one new warning rule in the authoring registry, its explanation entry and tests), the repo fixtures the card names only if the census forces an edit, a changeset (stop on breach; explain in the report)
Container & model: M, mode:thread, model: TIER_DEFAULT (dispatch-gates --tier: no path-derived mandate), effort: high (order); the thread runs the project default
Clause-②: no
Metadata-protocol: none
Responsibility: domain:server lint rule; the inert mask is author-written metadata (ruling A on #29106, 6573563853) · the platform path is the authoring registry (AUTHORING_RULES) · reached by any author who pairs a superuser bit with a field mask on one object
Thread-read: 6592587655
Premise: holds (on origin/maine0187d0f, no authoring rule reads a superuser bit beside a readable:false / editable:false entry; the dev pins red first)
Serial constraints cleared: #29558 (this seat) edits another rule in packages/lint; region-disjoint, the dev merges origin/main before the PR and after it lands. No other in-flight claim names packages/lint authoring rules.
Resume-from: none — fresh from origin/main
Measured by the dev:@objectstack/lint depends on @objectstack/spec only (its manifest: never on a runtime), so the rule mirrors holdsSuperuserBypass (packages/core/src/security/effective-object-permissions.ts) instead of importing it.
Parity pin route chosen: C. One new behavioural parity test in packages/cli/test/ (cli depends on both lint and core) that runs the lint mirror and core's holdsSuperuserBypass over the same case matrix (named object, '*' wildcard, both bits, neither) and asserts equal answers, so a core change that diverges reds it. Added to the file surface: that one new test file.
Not taken: A (a source-text equality read of core from a lint test) needs rows in scripts/cross-package-test-inputs.mjs and turbo.json, gate and root config outside this lane; B (a copied case table inside lint) never reds on a core change.
{
"issue": 29544,
"status": "done",
"branch": "claude/project-thread-dhnwh9",
"pr": "https://github.com/objectstack-ai/objectstack/pull/29724",
"session": "session_01JQwxbYxYhTvMoYjkUw8XvV",
"premise_still_valid": true,
"summary": "New warning security-superuser-field-mask-inert in validateSecurityPosture (the existing AUTHORING_RULES entry: os lint/validate/build and the runtime permission publish gate, where it lands under advisories, measured): a set holding View All on an object beside its own readable:false on that object, or Modify All beside readable:false or an edit lock, gets one finding per entry; View All beside an edit lock, a bypass in another set, and an explicit entry without the bits beside a '*' bypass get nothing. The bypass is read through a verbatim copy of core's holdsSuperuserBypass, exported from @objectstack/lint under the same name, and packages/cli/test/superuser-bypass-mirror-parity.test.ts pins the copy to core over a 410-case matrix (route C, claim amendment 6593310531). Census: examples (app-crm 2 sets, app-todo and app-multi-package 0), the showcase (9 sets) and the platform baseline (9 sets) give 0 findings; of the repo test fixtures only the admin-ledger dogfood's two composed sets fire (pinned as case 3). Head c20d3a56 includes two origin/main merges; the second auto-merged a sibling rule's lines in lint index.ts and rule-explanations.ts.",
"tests": "Red first on 61adbe57 (tests + id constant, no arm): vitest -t inert, 7 failed / 1 passed (the control). Final head c20d3a56 after building core... and lint...: pnpm --filter @objectstack/lint exec vitest run --maxWorkers=2 -> Test Files 192 passed (192), Tests 7942 passed (7942); pnpm --filter @objectstack/lint typecheck exit 0 (check:test-typecheck OK, debt unchanged); cli parity test (vitest --project unit, one file) 3/3. Ablation of the parity pin via scripts/ablation-replace.mjs under an EXIT trap, rule committed first: lint copy's lookup made wildcard-first (anchor 1 -> 0, blob df680307 -> 37845e72), lint rebuilt, ablation-dist-preflight with --source-marker exit 0 (marker in 4 dist files, tree reading passed), parity test 2 failed / 1 passed with 60 diverging cases; restored (blob == HEAD df680307, git diff HEAD empty), rebuilt, preflight --absent exit 0, parity 3/3. cli typecheck narrowed: the new file alone compiled under a scratch tsconfig extending packages/cli/tsconfig.test.json (--listFiles, exit 0, core and lint dist d.ts resolved); the full cli tsc is left to TypeScript Type Check (63-package closure).",
"gates": "head c20d3a56: dispatch-gates --commands --repo objectstack-ai/objectstack derived 58; all 58 recorded exit 0; --ran: 58 derived, 58 run, 0 NOT-MEASURED, 0 UNRUN. pnpm lint exit 0 (outside the derivation). First-head pass: check-plugin-teardown-shape --self-test exit 3 until git fetch --unshallow (then 48 cases pass), check:dual-build-cjs-loads exit 3 for missing dist (final head: 115 entry points / 70 packages load). PR check-runs on c20d3a56 when this report was written: 21 runs, 18 in_progress, 3 skipped; no conclusion yet (in_progress is the honest value).",
"dogfood_battery": "n/a — no ! in the PR title and Clause-② is no with no (narrowing) arm",
"mcp_calls": "0 — no GitHub MCP tool called",
"api_writes": "3 — git push (not a REST write, listed for the budget); relay pr_create (fleet-write dispatch, run 41568567263, read-back 12296 bytes sent = stored) -> #29724; post-stamped os-dev-report comment on #29544. Plus message_thread notes to the seat (not GitHub).",
"open_questions": [],
"security_findings": "none",
"out_of_scope_findings": [
"carrier: none · noted, not filed — admin-ledger-decision-metadata.dogfood.test.ts: by ruling A its withheld and wildcard readers are not actually withheld email (ald_withhold_set / ald_withhold_only_set carry View All on sys_user beside the email mask, which the file header calls a row-scope grant, not a field one); the file stays green because it asserts no reader is served a subject row at all, so no assertion rests on the mask. Seat decides whether it earns a card; dedupe words: admin ledger withheld email viewAllRecords inert mask dogfood"
],
"deviations": "File surface widened by the seat to packages/cli/test (claim amendment 6593310531). New public names: rule id security-superuser-field-mask-inert and the holdsSuperuserBypass export from @objectstack/lint (PM-discretion veto window). An OS_SKIP_DTS=1 build of the plugin-security closure for the census briefly left packages/spec/dist without d.ts; the first gate pass was stopped (only its first command had run), the closure rebuilt with DTS, and the gate pass restarted from zero.",
"body_amendments": []
}
MERGED by the merge queue at 2026-11-03T03:43Z, merge commit 51a12c07e90839b5f5a53db2161b87e81074513c
origin/main545c1c75
git grep "security-superuser-field-mask-inert" in packages/lint/src/validate-security-posture.ts: 2 hits (rule present)
State: closed by Fixes #29544 (completed); pm:dispatched removed. Delivered: the lint warning plus the holdsSuperuserBypass mirror with its core parity pin. Nothing left on this card. The admin-ledger dogfood note was dropped (recorded in ACCEPT 6594572672).
Activity
objectstack-fleet commentedon Nov 3, 2026
triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U
Path: none
Triage: first-touch audit · p3 kept ·
domain:serverkept for now · 2026-11-03T01:02Z⛔ Not a claim.
readable:false/editable:falseentry on the same object carries an inert mask. The card adds a warning lint finding. It never refuses anything, so it is advisory and not a gate. p3. The lane follows the filing seat pending thepackages/lintrouting ruling.Generated by Claude Code
objectstack-fleet commentedon Nov 3, 2026
domain:server#3 · os-warren · session_01JQwxbYyp6wSRcywGFK2L4A
Claim: PM loop round 2 · card thread · 2026-11-03T01:44Z
Session:
session_01JQwxbYyp6wSRcywGFK2L4A(the seat); the card thread issession_01JQwxbYxYhTvMoYjkUw8XvVAccount:
os-warren(the seat's linked user; the card's assignee)Branch:
claude/project-thread-dhnwh9(the card thread's harness-pinned branch; it names no issue, so this claim is the identity record)Worktree: the card thread's own container checkout
Domain:
domain:serverSeat:
domain:server#3File surface:
packages/lint/src/**(one new warning rule in the authoring registry, its explanation entry and tests), the repo fixtures the card names only if the census forces an edit, a changeset (stop on breach; explain in the report)Container & model:
M,mode:thread,model: TIER_DEFAULT (dispatch-gates --tier: no path-derived mandate),effort: high (order); the thread runs the project defaultClause-②: no
Metadata-protocol: none
Responsibility:
domain:serverlint rule; the inert mask is author-written metadata (ruling A on #29106, 6573563853) · the platform path is the authoring registry (AUTHORING_RULES) · reached by any author who pairs a superuser bit with a field mask on one objectThread-read: 6592587655
Premise: holds (on
origin/maine0187d0f, no authoring rule reads a superuser bit beside areadable:false/editable:falseentry; the dev pins red first)Serial constraints cleared: #29558 (this seat) edits another rule in
packages/lint; region-disjoint, the dev mergesorigin/mainbefore the PR and after it lands. No other in-flight claim namespackages/lintauthoring rules.Resume-from: none — fresh from
origin/mainState:
pm:queue→pm:dispatched, assigned toos-warren. Order: project folderpm-orders/server/seat3/order-29544.md.objectstack-fleet commentedon Nov 3, 2026
domain:server#3 · os-warren · session_01JQwxbYyp6wSRcywGFK2L4A
Claim amendment · #29544 · 2026-11-03T01:48Z · amends claim 6593237882 (same session, same branch
claude/project-thread-dhnwh9)@objectstack/lintdepends on@objectstack/speconly (its manifest: never on a runtime), so the rule mirrorsholdsSuperuserBypass(packages/core/src/security/effective-object-permissions.ts) instead of importing it.packages/cli/test/(cli depends on both lint and core) that runs the lint mirror and core'sholdsSuperuserBypassover the same case matrix (named object,'*'wildcard, both bits, neither) and asserts equal answers, so a core change that diverges reds it. Added to the file surface: that one new test file.scripts/cross-package-test-inputs.mjsandturbo.json, gate and root config outside this lane; B (a copied case table inside lint) never reds on a core change.objectstack-fleet commentedon Nov 3, 2026
domain:server#3 · os-warren · session_01JQwxbYxYhTvMoYjkUw8XvV
os-dev-report
{ "issue": 29544, "status": "done", "branch": "claude/project-thread-dhnwh9", "pr": "https://github.com/objectstack-ai/objectstack/pull/29724", "session": "session_01JQwxbYxYhTvMoYjkUw8XvV", "premise_still_valid": true, "summary": "New warning security-superuser-field-mask-inert in validateSecurityPosture (the existing AUTHORING_RULES entry: os lint/validate/build and the runtime permission publish gate, where it lands under advisories, measured): a set holding View All on an object beside its own readable:false on that object, or Modify All beside readable:false or an edit lock, gets one finding per entry; View All beside an edit lock, a bypass in another set, and an explicit entry without the bits beside a '*' bypass get nothing. The bypass is read through a verbatim copy of core's holdsSuperuserBypass, exported from @objectstack/lint under the same name, and packages/cli/test/superuser-bypass-mirror-parity.test.ts pins the copy to core over a 410-case matrix (route C, claim amendment 6593310531). Census: examples (app-crm 2 sets, app-todo and app-multi-package 0), the showcase (9 sets) and the platform baseline (9 sets) give 0 findings; of the repo test fixtures only the admin-ledger dogfood's two composed sets fire (pinned as case 3). Head c20d3a56 includes two origin/main merges; the second auto-merged a sibling rule's lines in lint index.ts and rule-explanations.ts.", "tests": "Red first on 61adbe57 (tests + id constant, no arm): vitest -t inert, 7 failed / 1 passed (the control). Final head c20d3a56 after building core... and lint...: pnpm --filter @objectstack/lint exec vitest run --maxWorkers=2 -> Test Files 192 passed (192), Tests 7942 passed (7942); pnpm --filter @objectstack/lint typecheck exit 0 (check:test-typecheck OK, debt unchanged); cli parity test (vitest --project unit, one file) 3/3. Ablation of the parity pin via scripts/ablation-replace.mjs under an EXIT trap, rule committed first: lint copy's lookup made wildcard-first (anchor 1 -> 0, blob df680307 -> 37845e72), lint rebuilt, ablation-dist-preflight with --source-marker exit 0 (marker in 4 dist files, tree reading passed), parity test 2 failed / 1 passed with 60 diverging cases; restored (blob == HEAD df680307, git diff HEAD empty), rebuilt, preflight --absent exit 0, parity 3/3. cli typecheck narrowed: the new file alone compiled under a scratch tsconfig extending packages/cli/tsconfig.test.json (--listFiles, exit 0, core and lint dist d.ts resolved); the full cli tsc is left to TypeScript Type Check (63-package closure).", "gates": "head c20d3a56: dispatch-gates --commands --repo objectstack-ai/objectstack derived 58; all 58 recorded exit 0; --ran: 58 derived, 58 run, 0 NOT-MEASURED, 0 UNRUN. pnpm lint exit 0 (outside the derivation). First-head pass: check-plugin-teardown-shape --self-test exit 3 until git fetch --unshallow (then 48 cases pass), check:dual-build-cjs-loads exit 3 for missing dist (final head: 115 entry points / 70 packages load). PR check-runs on c20d3a56 when this report was written: 21 runs, 18 in_progress, 3 skipped; no conclusion yet (in_progress is the honest value).", "dogfood_battery": "n/a — no ! in the PR title and Clause-② is no with no (narrowing) arm", "mcp_calls": "0 — no GitHub MCP tool called", "api_writes": "3 — git push (not a REST write, listed for the budget); relay pr_create (fleet-write dispatch, run 41568567263, read-back 12296 bytes sent = stored) -> #29724; post-stamped os-dev-report comment on #29544. Plus message_thread notes to the seat (not GitHub).", "open_questions": [], "security_findings": "none", "out_of_scope_findings": [ "carrier: none · noted, not filed — admin-ledger-decision-metadata.dogfood.test.ts: by ruling A its withheld and wildcard readers are not actually withheld email (ald_withhold_set / ald_withhold_only_set carry View All on sys_user beside the email mask, which the file header calls a row-scope grant, not a field one); the file stays green because it asserts no reader is served a subject row at all, so no assertion rests on the mask. Seat decides whether it earns a card; dedupe words: admin ledger withheld email viewAllRecords inert mask dogfood" ], "deviations": "File surface widened by the seat to packages/cli/test (claim amendment 6593310531). New public names: rule id security-superuser-field-mask-inert and the holdsSuperuserBypass export from @objectstack/lint (PM-discretion veto window). An OS_SKIP_DTS=1 build of the plugin-security closure for the census briefly left packages/spec/dist without d.ts; the first gate pass was stopped (only its first command had run), the closure rebuilt with DTS, and the gate pass restarted from zero.", "body_amendments": [] }objectstack-fleet commentedon Nov 3, 2026
domain:server#3 · os-warren · session_01JQwxbYyp6wSRcywGFK2L4A
Landed · 2026-11-03T03:44Z
51a12c07e90839b5f5a53db2161b87e81074513corigin/main545c1c75git grep "security-superuser-field-mask-inert"inpackages/lint/src/validate-security-posture.ts: 2 hits (rule present)State: closed by
Fixes #29544(completed);pm:dispatchedremoved. Delivered: the lint warning plus theholdsSuperuserBypassmirror with its core parity pin. Nothing left on this card. The admin-ledger dogfood note was dropped (recorded in ACCEPT 6594572672).