Uh oh!
There was an error while loading. Please reload this page.
docs(plugin-security): correct the managed-write-denies docblock on member_default - #14028
Conversation
…ember_default The module docblock still described `member_default` as granting CRUD through an `objects['*']` wildcard. #5491 removed that wildcard; the set's own declaration in `objects/default-permission-sets.ts` now opens by saying so. Comments only -- the non-comment diff is empty. Three sites in this file carried the same claim: the module docblock opening, the "engine-owned objects" section ("wildcard-granted in these sets"), and the `MANAGED_DENY_TARGET_SETS` docblock ("the sets whose `'*'` wildcard grants writes"). Each now names the mechanism that is actually in force per target set rather than leaving a gap where the false sentence was. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016ZC5rNQj3WEet5HAmmAkMs
📓 Docs Drift Check
What this run could not see
Coarse fallback — 14 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): |
Out-of-scope finding filed while implementing this card, per AGENTS.md Prime Directive #10: #14029 — Session: https://claude.ai/code/session_016ZC5rNQj3WEet5HAmmAkMs Generated by Claude Code Generated by Claude Code |
Uh oh!
There was an error while loading. Please reload this page.
Fixes#13822
Comments only. The module docblock of
managed-object-write-denies.tsstilldescribed
member_defaultas granting CRUD through anobjects['*']wildcard. #5491 removed that wildcard, and the set's own declaration in
objects/default-permission-sets.tsnow opens by saying the opposite.Premise verified first, on today's
origin/mainThe card's premise is a zero, so it is measured with the same-shaped non-zero
controls in the same run. A per-set census over
default-permission-sets.ts,comments stripped first so a
'*'in prose cannot be counted as adeclaration and a declaration cannot hide behind one:
member_defaultreads 0 while three sibling sets in the same run read 1, sothe zero is a reading and not a blind spot. Its only object spread is
...denyWritesOnManagedObjects(), whose keys areBETTER_AUTH_MANAGED_OBJECTS— no wildcard arrives that way either. The two sets reading 0 with a wildcard
elsewhere are known and named below.
So the granting shape today, for the four sets this module targets:
organization_adminviewAllRecords/modifyAllRecordsviewer_readonlymember_defaultTwo sets read 0 in the census but do hold a wildcard, neither of them
member_default:admin_full_accesstakes its fromADMIN_FULL_ACCESS_CAPABILITIESin@objectstack/spec, andorganization_admin_no_bypassis derived at module load byderiveWallLessOrgAdmin. Both are outside the census's file by construction,not missing from it.
What changed
Three sites in this one file carried the same claim; each now states the
mechanism in force rather than leaving the gap a deleted sentence would leave.
(...) grant CRUD via a
'*'wildcard". Replaced by the per-set breakdownabove, carrying
member_default's*wildcard object grant (C/R/E) union-merges into every org member — app-side explicit-allow object gates are erased on three axes #5491's reason and the 2026-08-07 maintainer ruling forwardfrom the sibling declaration.
sets" now reads "reached by the wildcard in the target sets that carry one",
and the
viewAllRecords/modifyAllRecordsargument namesorganization_admin, the only target set whose wildcard carries those bits.MANAGED_DENY_TARGET_SETSdocblock — "The default sets whose'*'wildcard grants writes" was the same false membership rule stated as a
definition. It now says what membership actually is, and points at the
module docblock for the per-set detail.
MANAGED_DENY_TARGET_SETS' membership is untouched — the deny entries areharmless and the list is a deliberate allowlist, exactly as the card says.
Verification
The non-comment diff is empty, and the comparator is proven live. Comments
stripped from both sides, whitespace collapsed, compared:
Syntactic parse, the one real failure mode of a docblock edit (a stray
*/closing the block early), with a live-detector control:ESLint, repo-wide, CI's own command —
pnpm lint=eslint . --no-inline-config— exit 0 in 117s. The edited file is confirmed inside the receiving population
rather than assumed to be:
--format jsonon that path returns 1 file entry,0 errors, 0 warnings, 0 suppressed messages.
Gate families re-derived from the actual diff with
node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack(no patharguments; exit 0), both sections read whole. 20 matched families plus the two
i18n convention gates. Exit codes captured before any pipe. All green except:
pnpm check:i18n— exit 1, NOT MEASURED: its own verdict line reads"PREREQUISITE NOT MET — the workspace CLI is not built ... Nothing was
checked". Its inputs are read rather than assumed: this plugin's
scripts/i18n-extract.config.tsimports six object definitions from../src/objects/index.jsplus the four generated bundles, andmanaged-object-write-denies.tsis named by neither — it is imported only bysecurity-plugin.tsand three test files.node scripts/check-test-completeness.mjs— exit 3, NOT MEASURED: itgrades a saved
turbo run testlog and none was named. Its own text saysthis is the expected local branch, not a red.
pnpm check:dual-build-cjs-loads— not run; it needs a full build. See thedeclared narrowing below.
Declared narrowing: the dependency-closure build, this package's vitest run
and
check:dual-build-cjs-loadswere not run locally. Stated as a narrowing,not reported as coverage. The shared verify lock was continuously held with 3-4
runs queued and waits of 340-685s throughout this task. Three readings say what
the narrowing does and does not exclude: (1) the compiled output is a function
of the non-comment source, and that source is identical on both sides — 1372
characters each, by a comparator a control proves live; (2) the diff is exactly
one path,
git diff --statreading 30 insertions / 14 deletions, all inside/** */blocks, with no config, tsconfig, package.json or test file touched,so no untouched file's verdict can move; (3) the file still parses clean under
the TypeScript parser and under ESLint's TypeScript parser, independently. CI
runs the farm on this PR regardless, which is where those three land.
A dispatch-gates staleness note is recorded rather than acted on: HEAD is 3
commits behind
origin/main(9b18c0475) and one file the derivation reads,scripts/import-prerequisite.mjs, changed across that range.Union re-run and all readings above are from
255eabdee, the branch head.Scope
No behaviour change: this is prose, and only prose. Out of scope and untouched,
per the dispatch:
packages/plugins/plugin-security/src/security-plugin.ts(read for the call site, never edited) and every other file on the in-flight
fence. #13903 is not addressed here — the repo-wide sweep of the retired
elevation-gate premise is its own face, its table names no line in this file,
and none of its rows are touched. No changeset: comments only, nothing
released, so this PR carries
skip-changeset.Generated by Claude Code
Generated by Claude Code