docs(plugin-security): correct the managed-write-denies docblock on member_default - #14028

Merged
os-steve merged 1 commit into
mainfrom
claude/issue-13822-managed-write-denies-docblock
Sep 1, 2026
Merged

docs(plugin-security): correct the managed-write-denies docblock on member_default#14028
os-steve merged 1 commit into
mainfrom
claude/issue-13822-managed-write-denies-docblock

Conversation

@claude

@claudeclaudeBot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Fixes#13822

Comments only. The module docblock of managed-object-write-denies.ts still
described member_default as granting CRUD through an objects['*']
wildcard. #5491 removed that wildcard, and the set's own declaration in
objects/default-permission-sets.ts now opens by saying the opposite.

Premise verified first, on today's origin/main

The 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 a
declaration and a declaration cannot hide behind one:

set (as declared) decl lines objects['*'] decls wildcard bits
ADMIN_FULL_ACCESS 132-177 0
ORGANIZATION_ADMIN 177-390 1 allowRead=true, allowCreate=true, allowEdit=true, allowDelete=true, viewAllRecords=true, modifyAllRecords=true
'member_default' 390-864 0
'viewer_readonly' 864-993 1 allowRead=true, allowCreate=false, allowEdit=false, allowDelete=false
MCP_AGENT_PERMISSION_SET_READ 993-1003 1 allowRead=true
MCP_AGENT_PERMISSION_SET_WRITE 1003-1018 1 allowRead=true, allowCreate=true, allowEdit=true, allowDelete=true
MCP_AGENT_PERMISSION_SET_RESTRICTED 1018-1049 0
ORGANIZATION_ADMIN_NO_BYPASS 1049-1074 0
TOTAL wildcard declarations in file: 4

member_default reads 0 while three sibling sets in the same run read 1, so
the zero is a reading and not a blind spot. Its only object spread is
...denyWritesOnManagedObjects(), whose keys are BETTER_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:

target setwildcardwhat the injected managed-table entry does there
organization_adminfull CRUD + viewAllRecords/modifyAllRecordsnarrows the wildcard
MCP write setfull CRUDnarrows the wildcard
viewer_readonlyread-onlybelt-and-suspenders over a wildcard that already denies (its own comment says so)
member_defaultnone since #5491it is the read grant itself — this set's access is exactly the objects it NAMES

Two sets read 0 in the census but do hold a wildcard, neither of them
member_default: admin_full_access takes its from
ADMIN_FULL_ACCESS_CAPABILITIES in @objectstack/spec, and
organization_admin_no_bypass is derived at module load by
deriveWallLessOrgAdmin. 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.

  1. Module docblock opening — "The default write-granting permission sets
    (...) grant CRUD via a '*' wildcard". Replaced by the per-set breakdown
    above, 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 forward
    from the sibling declaration.
  2. "Deliberately NOT covered" section — "are also wildcard-granted in these
    sets" now reads "reached by the wildcard in the target sets that carry one",
    and the viewAllRecords/modifyAllRecords argument names
    organization_admin, the only target set whose wildcard carries those bits.
  3. MANAGED_DENY_TARGET_SETS docblock — "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 are
harmless 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:

path : packages/plugins/plugin-security/src/managed-object-write-denies.ts
base ref : c54d4d3d7d0a7f3e6ec848dd0cb415ee35ebbb37
raw bytes : base=5664 working=6889 (differ: True)
non-comment chars : base=1372 working=1372
NON-COMMENT DIFF : EMPTY
CONTROL (one code line added to the working copy, comments untouched)
CONTROL non-comment diff : NON-EMPTY (comparator is live)

Syntactic parse, the one real failure mode of a docblock edit (a stray
*/ closing the block early), with a live-detector control:

 0 parse diagnostic(s) WORKING (after the docblock rewrite)
0 parse diagnostic(s) BASE c54d4d3d7 (control: known-good)
316 parse diagnostic(s) CONTROL (same file with a docblock closed early)
PARSE CHECK: PASS (and the detector is proven live by the control)

ESLint, repo-wide, CI's own commandpnpm lint = eslint . --no-inline-config
— exit 0 in 117s. The edited file is confirmed inside the receiving population
rather than assumed to be: --format json on 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 path
arguments; 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.ts imports six object definitions from
    ../src/objects/index.js plus the four generated bundles, and
    managed-object-write-denies.ts is named by neither — it is imported only by
    security-plugin.ts and three test files.
  • node scripts/check-test-completeness.mjs — exit 3, NOT MEASURED: it
    grades a saved turbo run test log and none was named. Its own text says
    this is the expected local branch, not a red.
  • pnpm check:dual-build-cjs-loads — not run; it needs a full build. See the
    declared narrowing below.

Declared narrowing: the dependency-closure build, this package's vitest run
and check:dual-build-cjs-loads were 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 --stat reading 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

…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
@claudeclaudeBot added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Sep 1, 2026
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

⚠️1 changed file(s) yielded no anchor (packages/plugins/plugin-security/src/managed-object-write-denies.ts), so the pages documenting them are NOT COVERED by this run — this is not a clean bill of health for those files. Nothing else in this diff resolved to a documentable surface (no symbol, route or SDK anchor derived from 1 changed package(s)).

What this run could not see
  • 1 changed file(s) yielded no anchor (packages/plugins/plugin-security/src/managed-object-write-denies.ts) — pages documenting those are invisible to this run
  • 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.

Coarse fallback — 14 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 e612dd0f5bac1313b4d8e2adb061521e210cb65fpackageMentionDocs.

@claude

claudeBot commented Sep 1, 2026

Copy link
Copy Markdown
ContributorAuthor

Out-of-scope finding filed while implementing this card, per AGENTS.md Prime Directive #10: #14029organization_admin_no_bypass holds a write-granting wildcard but is not in MANAGED_DENY_TARGET_SETS, so applyManagedWriteDenies walks past it and the registry-derived denies never reach it. Behaviour-class, deliberately NOT touched in this PR, which is prose only. Filed unassigned for triage.

Session: https://claude.ai/code/session_016ZC5rNQj3WEet5HAmmAkMs

Generated by Claude Code


Generated by Claude Code

@os-steve
os-steve marked this pull request as ready for review September 1, 2026 00:50
@os-steve
os-steve added this pull request to the merge queueSep 1, 2026
Merged via the queue into main with commit 0c95e34Sep 1, 2026
37 checks passed
@os-steve
os-steve deleted the claude/issue-13822-managed-write-denies-docblock branch September 1, 2026 01:20
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/sskip-changesetPR has no user-facing published change; bypasses the changeset gate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Stale docblock in managed-object-write-denies.ts still claims member_default grants CRUD via a '*' wildcard (removed by #5491)

2 participants

@os-steve@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

docs(plugin-security): correct the managed-write-denies docblock on member_default - #14028

Merged
os-steve merged 1 commit into
mainfrom
claude/issue-13822-managed-write-denies-docblock
Sep 1, 2026
Merged

docs(plugin-security): correct the managed-write-denies docblock on member_default#14028
os-steve merged 1 commit into
mainfrom
claude/issue-13822-managed-write-denies-docblock

Conversation

@claude

@claudeclaudeBot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Fixes#13822

Comments only. The module docblock of managed-object-write-denies.ts still
described member_default as granting CRUD through an objects['*']
wildcard. #5491 removed that wildcard, and the set's own declaration in
objects/default-permission-sets.ts now opens by saying the opposite.

Premise verified first, on today's origin/main

The 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 a
declaration and a declaration cannot hide behind one:

set (as declared) decl lines objects['*'] decls wildcard bits
ADMIN_FULL_ACCESS 132-177 0
ORGANIZATION_ADMIN 177-390 1 allowRead=true, allowCreate=true, allowEdit=true, allowDelete=true, viewAllRecords=true, modifyAllRecords=true
'member_default' 390-864 0
'viewer_readonly' 864-993 1 allowRead=true, allowCreate=false, allowEdit=false, allowDelete=false
MCP_AGENT_PERMISSION_SET_READ 993-1003 1 allowRead=true
MCP_AGENT_PERMISSION_SET_WRITE 1003-1018 1 allowRead=true, allowCreate=true, allowEdit=true, allowDelete=true
MCP_AGENT_PERMISSION_SET_RESTRICTED 1018-1049 0
ORGANIZATION_ADMIN_NO_BYPASS 1049-1074 0
TOTAL wildcard declarations in file: 4

member_default reads 0 while three sibling sets in the same run read 1, so
the zero is a reading and not a blind spot. Its only object spread is
...denyWritesOnManagedObjects(), whose keys are BETTER_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:

target setwildcardwhat the injected managed-table entry does there
organization_adminfull CRUD + viewAllRecords/modifyAllRecordsnarrows the wildcard
MCP write setfull CRUDnarrows the wildcard
viewer_readonlyread-onlybelt-and-suspenders over a wildcard that already denies (its own comment says so)
member_defaultnone since #5491it is the read grant itself — this set's access is exactly the objects it NAMES

Two sets read 0 in the census but do hold a wildcard, neither of them
member_default: admin_full_access takes its from
ADMIN_FULL_ACCESS_CAPABILITIES in @objectstack/spec, and
organization_admin_no_bypass is derived at module load by
deriveWallLessOrgAdmin. 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.

  1. Module docblock opening — "The default write-granting permission sets
    (...) grant CRUD via a '*' wildcard". Replaced by the per-set breakdown
    above, 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 forward
    from the sibling declaration.
  2. "Deliberately NOT covered" section — "are also wildcard-granted in these
    sets" now reads "reached by the wildcard in the target sets that carry one",
    and the viewAllRecords/modifyAllRecords argument names
    organization_admin, the only target set whose wildcard carries those bits.
  3. MANAGED_DENY_TARGET_SETS docblock — "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 are
harmless 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:

path : packages/plugins/plugin-security/src/managed-object-write-denies.ts
base ref : c54d4d3d7d0a7f3e6ec848dd0cb415ee35ebbb37
raw bytes : base=5664 working=6889 (differ: True)
non-comment chars : base=1372 working=1372
NON-COMMENT DIFF : EMPTY
CONTROL (one code line added to the working copy, comments untouched)
CONTROL non-comment diff : NON-EMPTY (comparator is live)

Syntactic parse, the one real failure mode of a docblock edit (a stray
*/ closing the block early), with a live-detector control:

 0 parse diagnostic(s) WORKING (after the docblock rewrite)
0 parse diagnostic(s) BASE c54d4d3d7 (control: known-good)
316 parse diagnostic(s) CONTROL (same file with a docblock closed early)
PARSE CHECK: PASS (and the detector is proven live by the control)

ESLint, repo-wide, CI's own commandpnpm lint = eslint . --no-inline-config
— exit 0 in 117s. The edited file is confirmed inside the receiving population
rather than assumed to be: --format json on 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 path
arguments; 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.ts imports six object definitions from
    ../src/objects/index.js plus the four generated bundles, and
    managed-object-write-denies.ts is named by neither — it is imported only by
    security-plugin.ts and three test files.
  • node scripts/check-test-completeness.mjs — exit 3, NOT MEASURED: it
    grades a saved turbo run test log and none was named. Its own text says
    this is the expected local branch, not a red.
  • pnpm check:dual-build-cjs-loads — not run; it needs a full build. See the
    declared narrowing below.

Declared narrowing: the dependency-closure build, this package's vitest run
and check:dual-build-cjs-loads were 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 --stat reading 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

…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
@claudeclaudeBot added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Sep 1, 2026
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

⚠️1 changed file(s) yielded no anchor (packages/plugins/plugin-security/src/managed-object-write-denies.ts), so the pages documenting them are NOT COVERED by this run — this is not a clean bill of health for those files. Nothing else in this diff resolved to a documentable surface (no symbol, route or SDK anchor derived from 1 changed package(s)).

What this run could not see
  • 1 changed file(s) yielded no anchor (packages/plugins/plugin-security/src/managed-object-write-denies.ts) — pages documenting those are invisible to this run
  • 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.

Coarse fallback — 14 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 e612dd0f5bac1313b4d8e2adb061521e210cb65fpackageMentionDocs.

@claude

claudeBot commented Sep 1, 2026

Copy link
Copy Markdown
ContributorAuthor

Out-of-scope finding filed while implementing this card, per AGENTS.md Prime Directive #10: #14029organization_admin_no_bypass holds a write-granting wildcard but is not in MANAGED_DENY_TARGET_SETS, so applyManagedWriteDenies walks past it and the registry-derived denies never reach it. Behaviour-class, deliberately NOT touched in this PR, which is prose only. Filed unassigned for triage.

Session: https://claude.ai/code/session_016ZC5rNQj3WEet5HAmmAkMs

Generated by Claude Code


Generated by Claude Code

@os-steve
os-steve marked this pull request as ready for review September 1, 2026 00:50
@os-steve
os-steve added this pull request to the merge queueSep 1, 2026
Merged via the queue into main with commit 0c95e34Sep 1, 2026
37 checks passed
@os-steve
os-steve deleted the claude/issue-13822-managed-write-denies-docblock branch September 1, 2026 01:20
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/sskip-changesetPR has no user-facing published change; bypasses the changeset gate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Stale docblock in managed-object-write-denies.ts still claims member_default grants CRUD via a '*' wildcard (removed by #5491)

2 participants

@os-steve@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

docs(plugin-security): correct the managed-write-denies docblock on member_default - #14028

Merged
os-steve merged 1 commit into
mainfrom
claude/issue-13822-managed-write-denies-docblock
Sep 1, 2026
Merged

docs(plugin-security): correct the managed-write-denies docblock on member_default#14028
os-steve merged 1 commit into
mainfrom
claude/issue-13822-managed-write-denies-docblock

Conversation

@claude

@claudeclaudeBot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Fixes#13822

Comments only. The module docblock of managed-object-write-denies.ts still
described member_default as granting CRUD through an objects['*']
wildcard. #5491 removed that wildcard, and the set's own declaration in
objects/default-permission-sets.ts now opens by saying the opposite.

Premise verified first, on today's origin/main

The 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 a
declaration and a declaration cannot hide behind one:

set (as declared) decl lines objects['*'] decls wildcard bits
ADMIN_FULL_ACCESS 132-177 0
ORGANIZATION_ADMIN 177-390 1 allowRead=true, allowCreate=true, allowEdit=true, allowDelete=true, viewAllRecords=true, modifyAllRecords=true
'member_default' 390-864 0
'viewer_readonly' 864-993 1 allowRead=true, allowCreate=false, allowEdit=false, allowDelete=false
MCP_AGENT_PERMISSION_SET_READ 993-1003 1 allowRead=true
MCP_AGENT_PERMISSION_SET_WRITE 1003-1018 1 allowRead=true, allowCreate=true, allowEdit=true, allowDelete=true
MCP_AGENT_PERMISSION_SET_RESTRICTED 1018-1049 0
ORGANIZATION_ADMIN_NO_BYPASS 1049-1074 0
TOTAL wildcard declarations in file: 4

member_default reads 0 while three sibling sets in the same run read 1, so
the zero is a reading and not a blind spot. Its only object spread is
...denyWritesOnManagedObjects(), whose keys are BETTER_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:

target setwildcardwhat the injected managed-table entry does there
organization_adminfull CRUD + viewAllRecords/modifyAllRecordsnarrows the wildcard
MCP write setfull CRUDnarrows the wildcard
viewer_readonlyread-onlybelt-and-suspenders over a wildcard that already denies (its own comment says so)
member_defaultnone since #5491it is the read grant itself — this set's access is exactly the objects it NAMES

Two sets read 0 in the census but do hold a wildcard, neither of them
member_default: admin_full_access takes its from
ADMIN_FULL_ACCESS_CAPABILITIES in @objectstack/spec, and
organization_admin_no_bypass is derived at module load by
deriveWallLessOrgAdmin. 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.

  1. Module docblock opening — "The default write-granting permission sets
    (...) grant CRUD via a '*' wildcard". Replaced by the per-set breakdown
    above, 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 forward
    from the sibling declaration.
  2. "Deliberately NOT covered" section — "are also wildcard-granted in these
    sets" now reads "reached by the wildcard in the target sets that carry one",
    and the viewAllRecords/modifyAllRecords argument names
    organization_admin, the only target set whose wildcard carries those bits.
  3. MANAGED_DENY_TARGET_SETS docblock — "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 are
harmless 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:

path : packages/plugins/plugin-security/src/managed-object-write-denies.ts
base ref : c54d4d3d7d0a7f3e6ec848dd0cb415ee35ebbb37
raw bytes : base=5664 working=6889 (differ: True)
non-comment chars : base=1372 working=1372
NON-COMMENT DIFF : EMPTY
CONTROL (one code line added to the working copy, comments untouched)
CONTROL non-comment diff : NON-EMPTY (comparator is live)

Syntactic parse, the one real failure mode of a docblock edit (a stray
*/ closing the block early), with a live-detector control:

 0 parse diagnostic(s) WORKING (after the docblock rewrite)
0 parse diagnostic(s) BASE c54d4d3d7 (control: known-good)
316 parse diagnostic(s) CONTROL (same file with a docblock closed early)
PARSE CHECK: PASS (and the detector is proven live by the control)

ESLint, repo-wide, CI's own commandpnpm lint = eslint . --no-inline-config
— exit 0 in 117s. The edited file is confirmed inside the receiving population
rather than assumed to be: --format json on 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 path
arguments; 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.ts imports six object definitions from
    ../src/objects/index.js plus the four generated bundles, and
    managed-object-write-denies.ts is named by neither — it is imported only by
    security-plugin.ts and three test files.
  • node scripts/check-test-completeness.mjs — exit 3, NOT MEASURED: it
    grades a saved turbo run test log and none was named. Its own text says
    this is the expected local branch, not a red.
  • pnpm check:dual-build-cjs-loads — not run; it needs a full build. See the
    declared narrowing below.

Declared narrowing: the dependency-closure build, this package's vitest run
and check:dual-build-cjs-loads were 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 --stat reading 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

…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
@claudeclaudeBot added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Sep 1, 2026
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

⚠️1 changed file(s) yielded no anchor (packages/plugins/plugin-security/src/managed-object-write-denies.ts), so the pages documenting them are NOT COVERED by this run — this is not a clean bill of health for those files. Nothing else in this diff resolved to a documentable surface (no symbol, route or SDK anchor derived from 1 changed package(s)).

What this run could not see
  • 1 changed file(s) yielded no anchor (packages/plugins/plugin-security/src/managed-object-write-denies.ts) — pages documenting those are invisible to this run
  • 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.

Coarse fallback — 14 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 e612dd0f5bac1313b4d8e2adb061521e210cb65fpackageMentionDocs.

@claude

claudeBot commented Sep 1, 2026

Copy link
Copy Markdown
ContributorAuthor

Out-of-scope finding filed while implementing this card, per AGENTS.md Prime Directive #10: #14029organization_admin_no_bypass holds a write-granting wildcard but is not in MANAGED_DENY_TARGET_SETS, so applyManagedWriteDenies walks past it and the registry-derived denies never reach it. Behaviour-class, deliberately NOT touched in this PR, which is prose only. Filed unassigned for triage.

Session: https://claude.ai/code/session_016ZC5rNQj3WEet5HAmmAkMs

Generated by Claude Code


Generated by Claude Code

@os-steve
os-steve marked this pull request as ready for review September 1, 2026 00:50
@os-steve
os-steve added this pull request to the merge queueSep 1, 2026
Merged via the queue into main with commit 0c95e34Sep 1, 2026
37 checks passed
@os-steve
os-steve deleted the claude/issue-13822-managed-write-denies-docblock branch September 1, 2026 01:20
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/sskip-changesetPR has no user-facing published change; bypasses the changeset gate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Stale docblock in managed-object-write-denies.ts still claims member_default grants CRUD via a '*' wildcard (removed by #5491)

2 participants

@os-steve@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

docs(plugin-security): correct the managed-write-denies docblock on member_default - #14028

Merged
os-steve merged 1 commit into
mainfrom
claude/issue-13822-managed-write-denies-docblock
Sep 1, 2026
Merged

docs(plugin-security): correct the managed-write-denies docblock on member_default#14028
os-steve merged 1 commit into
mainfrom
claude/issue-13822-managed-write-denies-docblock

Conversation

@claude

@claudeclaudeBot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Fixes#13822

Comments only. The module docblock of managed-object-write-denies.ts still
described member_default as granting CRUD through an objects['*']
wildcard. #5491 removed that wildcard, and the set's own declaration in
objects/default-permission-sets.ts now opens by saying the opposite.

Premise verified first, on today's origin/main

The 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 a
declaration and a declaration cannot hide behind one:

set (as declared) decl lines objects['*'] decls wildcard bits
ADMIN_FULL_ACCESS 132-177 0
ORGANIZATION_ADMIN 177-390 1 allowRead=true, allowCreate=true, allowEdit=true, allowDelete=true, viewAllRecords=true, modifyAllRecords=true
'member_default' 390-864 0
'viewer_readonly' 864-993 1 allowRead=true, allowCreate=false, allowEdit=false, allowDelete=false
MCP_AGENT_PERMISSION_SET_READ 993-1003 1 allowRead=true
MCP_AGENT_PERMISSION_SET_WRITE 1003-1018 1 allowRead=true, allowCreate=true, allowEdit=true, allowDelete=true
MCP_AGENT_PERMISSION_SET_RESTRICTED 1018-1049 0
ORGANIZATION_ADMIN_NO_BYPASS 1049-1074 0
TOTAL wildcard declarations in file: 4

member_default reads 0 while three sibling sets in the same run read 1, so
the zero is a reading and not a blind spot. Its only object spread is
...denyWritesOnManagedObjects(), whose keys are BETTER_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:

target setwildcardwhat the injected managed-table entry does there
organization_adminfull CRUD + viewAllRecords/modifyAllRecordsnarrows the wildcard
MCP write setfull CRUDnarrows the wildcard
viewer_readonlyread-onlybelt-and-suspenders over a wildcard that already denies (its own comment says so)
member_defaultnone since #5491it is the read grant itself — this set's access is exactly the objects it NAMES

Two sets read 0 in the census but do hold a wildcard, neither of them
member_default: admin_full_access takes its from
ADMIN_FULL_ACCESS_CAPABILITIES in @objectstack/spec, and
organization_admin_no_bypass is derived at module load by
deriveWallLessOrgAdmin. 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.

  1. Module docblock opening — "The default write-granting permission sets
    (...) grant CRUD via a '*' wildcard". Replaced by the per-set breakdown
    above, 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 forward
    from the sibling declaration.
  2. "Deliberately NOT covered" section — "are also wildcard-granted in these
    sets" now reads "reached by the wildcard in the target sets that carry one",
    and the viewAllRecords/modifyAllRecords argument names
    organization_admin, the only target set whose wildcard carries those bits.
  3. MANAGED_DENY_TARGET_SETS docblock — "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 are
harmless 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:

path : packages/plugins/plugin-security/src/managed-object-write-denies.ts
base ref : c54d4d3d7d0a7f3e6ec848dd0cb415ee35ebbb37
raw bytes : base=5664 working=6889 (differ: True)
non-comment chars : base=1372 working=1372
NON-COMMENT DIFF : EMPTY
CONTROL (one code line added to the working copy, comments untouched)
CONTROL non-comment diff : NON-EMPTY (comparator is live)

Syntactic parse, the one real failure mode of a docblock edit (a stray
*/ closing the block early), with a live-detector control:

 0 parse diagnostic(s) WORKING (after the docblock rewrite)
0 parse diagnostic(s) BASE c54d4d3d7 (control: known-good)
316 parse diagnostic(s) CONTROL (same file with a docblock closed early)
PARSE CHECK: PASS (and the detector is proven live by the control)

ESLint, repo-wide, CI's own commandpnpm lint = eslint . --no-inline-config
— exit 0 in 117s. The edited file is confirmed inside the receiving population
rather than assumed to be: --format json on 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 path
arguments; 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.ts imports six object definitions from
    ../src/objects/index.js plus the four generated bundles, and
    managed-object-write-denies.ts is named by neither — it is imported only by
    security-plugin.ts and three test files.
  • node scripts/check-test-completeness.mjs — exit 3, NOT MEASURED: it
    grades a saved turbo run test log and none was named. Its own text says
    this is the expected local branch, not a red.
  • pnpm check:dual-build-cjs-loads — not run; it needs a full build. See the
    declared narrowing below.

Declared narrowing: the dependency-closure build, this package's vitest run
and check:dual-build-cjs-loads were 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 --stat reading 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

…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
@claudeclaudeBot added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Sep 1, 2026
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

⚠️1 changed file(s) yielded no anchor (packages/plugins/plugin-security/src/managed-object-write-denies.ts), so the pages documenting them are NOT COVERED by this run — this is not a clean bill of health for those files. Nothing else in this diff resolved to a documentable surface (no symbol, route or SDK anchor derived from 1 changed package(s)).

What this run could not see
  • 1 changed file(s) yielded no anchor (packages/plugins/plugin-security/src/managed-object-write-denies.ts) — pages documenting those are invisible to this run
  • 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.

Coarse fallback — 14 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 e612dd0f5bac1313b4d8e2adb061521e210cb65fpackageMentionDocs.

@claude

claudeBot commented Sep 1, 2026

Copy link
Copy Markdown
ContributorAuthor

Out-of-scope finding filed while implementing this card, per AGENTS.md Prime Directive #10: #14029organization_admin_no_bypass holds a write-granting wildcard but is not in MANAGED_DENY_TARGET_SETS, so applyManagedWriteDenies walks past it and the registry-derived denies never reach it. Behaviour-class, deliberately NOT touched in this PR, which is prose only. Filed unassigned for triage.

Session: https://claude.ai/code/session_016ZC5rNQj3WEet5HAmmAkMs

Generated by Claude Code


Generated by Claude Code

@os-steve
os-steve marked this pull request as ready for review September 1, 2026 00:50
@os-steve
os-steve added this pull request to the merge queueSep 1, 2026
Merged via the queue into main with commit 0c95e34Sep 1, 2026
37 checks passed
@os-steve
os-steve deleted the claude/issue-13822-managed-write-denies-docblock branch September 1, 2026 01:20
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/sskip-changesetPR has no user-facing published change; bypasses the changeset gate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Stale docblock in managed-object-write-denies.ts still claims member_default grants CRUD via a '*' wildcard (removed by #5491)

2 participants

@os-steve@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

docs(plugin-security): correct the managed-write-denies docblock on member_default - #14028

Merged
os-steve merged 1 commit into
mainfrom
claude/issue-13822-managed-write-denies-docblock
Sep 1, 2026
Merged

docs(plugin-security): correct the managed-write-denies docblock on member_default#14028
os-steve merged 1 commit into
mainfrom
claude/issue-13822-managed-write-denies-docblock

Conversation

@claude

@claudeclaudeBot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Fixes#13822

Comments only. The module docblock of managed-object-write-denies.ts still
described member_default as granting CRUD through an objects['*']
wildcard. #5491 removed that wildcard, and the set's own declaration in
objects/default-permission-sets.ts now opens by saying the opposite.

Premise verified first, on today's origin/main

The 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 a
declaration and a declaration cannot hide behind one:

set (as declared) decl lines objects['*'] decls wildcard bits
ADMIN_FULL_ACCESS 132-177 0
ORGANIZATION_ADMIN 177-390 1 allowRead=true, allowCreate=true, allowEdit=true, allowDelete=true, viewAllRecords=true, modifyAllRecords=true
'member_default' 390-864 0
'viewer_readonly' 864-993 1 allowRead=true, allowCreate=false, allowEdit=false, allowDelete=false
MCP_AGENT_PERMISSION_SET_READ 993-1003 1 allowRead=true
MCP_AGENT_PERMISSION_SET_WRITE 1003-1018 1 allowRead=true, allowCreate=true, allowEdit=true, allowDelete=true
MCP_AGENT_PERMISSION_SET_RESTRICTED 1018-1049 0
ORGANIZATION_ADMIN_NO_BYPASS 1049-1074 0
TOTAL wildcard declarations in file: 4

member_default reads 0 while three sibling sets in the same run read 1, so
the zero is a reading and not a blind spot. Its only object spread is
...denyWritesOnManagedObjects(), whose keys are BETTER_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:

target setwildcardwhat the injected managed-table entry does there
organization_adminfull CRUD + viewAllRecords/modifyAllRecordsnarrows the wildcard
MCP write setfull CRUDnarrows the wildcard
viewer_readonlyread-onlybelt-and-suspenders over a wildcard that already denies (its own comment says so)
member_defaultnone since #5491it is the read grant itself — this set's access is exactly the objects it NAMES

Two sets read 0 in the census but do hold a wildcard, neither of them
member_default: admin_full_access takes its from
ADMIN_FULL_ACCESS_CAPABILITIES in @objectstack/spec, and
organization_admin_no_bypass is derived at module load by
deriveWallLessOrgAdmin. 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.

  1. Module docblock opening — "The default write-granting permission sets
    (...) grant CRUD via a '*' wildcard". Replaced by the per-set breakdown
    above, 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 forward
    from the sibling declaration.
  2. "Deliberately NOT covered" section — "are also wildcard-granted in these
    sets" now reads "reached by the wildcard in the target sets that carry one",
    and the viewAllRecords/modifyAllRecords argument names
    organization_admin, the only target set whose wildcard carries those bits.
  3. MANAGED_DENY_TARGET_SETS docblock — "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 are
harmless 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:

path : packages/plugins/plugin-security/src/managed-object-write-denies.ts
base ref : c54d4d3d7d0a7f3e6ec848dd0cb415ee35ebbb37
raw bytes : base=5664 working=6889 (differ: True)
non-comment chars : base=1372 working=1372
NON-COMMENT DIFF : EMPTY
CONTROL (one code line added to the working copy, comments untouched)
CONTROL non-comment diff : NON-EMPTY (comparator is live)

Syntactic parse, the one real failure mode of a docblock edit (a stray
*/ closing the block early), with a live-detector control:

 0 parse diagnostic(s) WORKING (after the docblock rewrite)
0 parse diagnostic(s) BASE c54d4d3d7 (control: known-good)
316 parse diagnostic(s) CONTROL (same file with a docblock closed early)
PARSE CHECK: PASS (and the detector is proven live by the control)

ESLint, repo-wide, CI's own commandpnpm lint = eslint . --no-inline-config
— exit 0 in 117s. The edited file is confirmed inside the receiving population
rather than assumed to be: --format json on 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 path
arguments; 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.ts imports six object definitions from
    ../src/objects/index.js plus the four generated bundles, and
    managed-object-write-denies.ts is named by neither — it is imported only by
    security-plugin.ts and three test files.
  • node scripts/check-test-completeness.mjs — exit 3, NOT MEASURED: it
    grades a saved turbo run test log and none was named. Its own text says
    this is the expected local branch, not a red.
  • pnpm check:dual-build-cjs-loads — not run; it needs a full build. See the
    declared narrowing below.

Declared narrowing: the dependency-closure build, this package's vitest run
and check:dual-build-cjs-loads were 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 --stat reading 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

…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
@claudeclaudeBot added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Sep 1, 2026
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

⚠️1 changed file(s) yielded no anchor (packages/plugins/plugin-security/src/managed-object-write-denies.ts), so the pages documenting them are NOT COVERED by this run — this is not a clean bill of health for those files. Nothing else in this diff resolved to a documentable surface (no symbol, route or SDK anchor derived from 1 changed package(s)).

What this run could not see
  • 1 changed file(s) yielded no anchor (packages/plugins/plugin-security/src/managed-object-write-denies.ts) — pages documenting those are invisible to this run
  • 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.

Coarse fallback — 14 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 e612dd0f5bac1313b4d8e2adb061521e210cb65fpackageMentionDocs.

@claude

claudeBot commented Sep 1, 2026

Copy link
Copy Markdown
ContributorAuthor

Out-of-scope finding filed while implementing this card, per AGENTS.md Prime Directive #10: #14029organization_admin_no_bypass holds a write-granting wildcard but is not in MANAGED_DENY_TARGET_SETS, so applyManagedWriteDenies walks past it and the registry-derived denies never reach it. Behaviour-class, deliberately NOT touched in this PR, which is prose only. Filed unassigned for triage.

Session: https://claude.ai/code/session_016ZC5rNQj3WEet5HAmmAkMs

Generated by Claude Code


Generated by Claude Code

@os-steve
os-steve marked this pull request as ready for review September 1, 2026 00:50
@os-steve
os-steve added this pull request to the merge queueSep 1, 2026
Merged via the queue into main with commit 0c95e34Sep 1, 2026
37 checks passed
@os-steve
os-steve deleted the claude/issue-13822-managed-write-denies-docblock branch September 1, 2026 01:20
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/sskip-changesetPR has no user-facing published change; bypasses the changeset gate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Stale docblock in managed-object-write-denies.ts still claims member_default grants CRUD via a '*' wildcard (removed by #5491)

2 participants

@os-steve@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

docs(plugin-security): correct the managed-write-denies docblock on member_default - #14028

Merged
os-steve merged 1 commit into
mainfrom
claude/issue-13822-managed-write-denies-docblock
Sep 1, 2026
Merged

docs(plugin-security): correct the managed-write-denies docblock on member_default#14028
os-steve merged 1 commit into
mainfrom
claude/issue-13822-managed-write-denies-docblock

Conversation

@claude

@claudeclaudeBot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Fixes#13822

Comments only. The module docblock of managed-object-write-denies.ts still
described member_default as granting CRUD through an objects['*']
wildcard. #5491 removed that wildcard, and the set's own declaration in
objects/default-permission-sets.ts now opens by saying the opposite.

Premise verified first, on today's origin/main

The 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 a
declaration and a declaration cannot hide behind one:

set (as declared) decl lines objects['*'] decls wildcard bits
ADMIN_FULL_ACCESS 132-177 0
ORGANIZATION_ADMIN 177-390 1 allowRead=true, allowCreate=true, allowEdit=true, allowDelete=true, viewAllRecords=true, modifyAllRecords=true
'member_default' 390-864 0
'viewer_readonly' 864-993 1 allowRead=true, allowCreate=false, allowEdit=false, allowDelete=false
MCP_AGENT_PERMISSION_SET_READ 993-1003 1 allowRead=true
MCP_AGENT_PERMISSION_SET_WRITE 1003-1018 1 allowRead=true, allowCreate=true, allowEdit=true, allowDelete=true
MCP_AGENT_PERMISSION_SET_RESTRICTED 1018-1049 0
ORGANIZATION_ADMIN_NO_BYPASS 1049-1074 0
TOTAL wildcard declarations in file: 4

member_default reads 0 while three sibling sets in the same run read 1, so
the zero is a reading and not a blind spot. Its only object spread is
...denyWritesOnManagedObjects(), whose keys are BETTER_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:

target setwildcardwhat the injected managed-table entry does there
organization_adminfull CRUD + viewAllRecords/modifyAllRecordsnarrows the wildcard
MCP write setfull CRUDnarrows the wildcard
viewer_readonlyread-onlybelt-and-suspenders over a wildcard that already denies (its own comment says so)
member_defaultnone since #5491it is the read grant itself — this set's access is exactly the objects it NAMES

Two sets read 0 in the census but do hold a wildcard, neither of them
member_default: admin_full_access takes its from
ADMIN_FULL_ACCESS_CAPABILITIES in @objectstack/spec, and
organization_admin_no_bypass is derived at module load by
deriveWallLessOrgAdmin. 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.

  1. Module docblock opening — "The default write-granting permission sets
    (...) grant CRUD via a '*' wildcard". Replaced by the per-set breakdown
    above, 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 forward
    from the sibling declaration.
  2. "Deliberately NOT covered" section — "are also wildcard-granted in these
    sets" now reads "reached by the wildcard in the target sets that carry one",
    and the viewAllRecords/modifyAllRecords argument names
    organization_admin, the only target set whose wildcard carries those bits.
  3. MANAGED_DENY_TARGET_SETS docblock — "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 are
harmless 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:

path : packages/plugins/plugin-security/src/managed-object-write-denies.ts
base ref : c54d4d3d7d0a7f3e6ec848dd0cb415ee35ebbb37
raw bytes : base=5664 working=6889 (differ: True)
non-comment chars : base=1372 working=1372
NON-COMMENT DIFF : EMPTY
CONTROL (one code line added to the working copy, comments untouched)
CONTROL non-comment diff : NON-EMPTY (comparator is live)

Syntactic parse, the one real failure mode of a docblock edit (a stray
*/ closing the block early), with a live-detector control:

 0 parse diagnostic(s) WORKING (after the docblock rewrite)
0 parse diagnostic(s) BASE c54d4d3d7 (control: known-good)
316 parse diagnostic(s) CONTROL (same file with a docblock closed early)
PARSE CHECK: PASS (and the detector is proven live by the control)

ESLint, repo-wide, CI's own commandpnpm lint = eslint . --no-inline-config
— exit 0 in 117s. The edited file is confirmed inside the receiving population
rather than assumed to be: --format json on 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 path
arguments; 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.ts imports six object definitions from
    ../src/objects/index.js plus the four generated bundles, and
    managed-object-write-denies.ts is named by neither — it is imported only by
    security-plugin.ts and three test files.
  • node scripts/check-test-completeness.mjs — exit 3, NOT MEASURED: it
    grades a saved turbo run test log and none was named. Its own text says
    this is the expected local branch, not a red.
  • pnpm check:dual-build-cjs-loads — not run; it needs a full build. See the
    declared narrowing below.

Declared narrowing: the dependency-closure build, this package's vitest run
and check:dual-build-cjs-loads were 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 --stat reading 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

…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
@claudeclaudeBot added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Sep 1, 2026
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

⚠️1 changed file(s) yielded no anchor (packages/plugins/plugin-security/src/managed-object-write-denies.ts), so the pages documenting them are NOT COVERED by this run — this is not a clean bill of health for those files. Nothing else in this diff resolved to a documentable surface (no symbol, route or SDK anchor derived from 1 changed package(s)).

What this run could not see
  • 1 changed file(s) yielded no anchor (packages/plugins/plugin-security/src/managed-object-write-denies.ts) — pages documenting those are invisible to this run
  • 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.

Coarse fallback — 14 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 e612dd0f5bac1313b4d8e2adb061521e210cb65fpackageMentionDocs.

@claude

claudeBot commented Sep 1, 2026

Copy link
Copy Markdown
ContributorAuthor

Out-of-scope finding filed while implementing this card, per AGENTS.md Prime Directive #10: #14029organization_admin_no_bypass holds a write-granting wildcard but is not in MANAGED_DENY_TARGET_SETS, so applyManagedWriteDenies walks past it and the registry-derived denies never reach it. Behaviour-class, deliberately NOT touched in this PR, which is prose only. Filed unassigned for triage.

Session: https://claude.ai/code/session_016ZC5rNQj3WEet5HAmmAkMs

Generated by Claude Code


Generated by Claude Code

@os-steve
os-steve marked this pull request as ready for review September 1, 2026 00:50
@os-steve
os-steve added this pull request to the merge queueSep 1, 2026
Merged via the queue into main with commit 0c95e34Sep 1, 2026
37 checks passed
@os-steve
os-steve deleted the claude/issue-13822-managed-write-denies-docblock branch September 1, 2026 01:20
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/sskip-changesetPR has no user-facing published change; bypasses the changeset gate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Stale docblock in managed-object-write-denies.ts still claims member_default grants CRUD via a '*' wildcard (removed by #5491)

2 participants

@os-steve@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

docs(plugin-security): correct the managed-write-denies docblock on member_default - #14028

Merged
os-steve merged 1 commit into
mainfrom
claude/issue-13822-managed-write-denies-docblock
Sep 1, 2026
Merged

docs(plugin-security): correct the managed-write-denies docblock on member_default#14028
os-steve merged 1 commit into
mainfrom
claude/issue-13822-managed-write-denies-docblock

Conversation

@claude

@claudeclaudeBot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Fixes#13822

Comments only. The module docblock of managed-object-write-denies.ts still
described member_default as granting CRUD through an objects['*']
wildcard. #5491 removed that wildcard, and the set's own declaration in
objects/default-permission-sets.ts now opens by saying the opposite.

Premise verified first, on today's origin/main

The 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 a
declaration and a declaration cannot hide behind one:

set (as declared) decl lines objects['*'] decls wildcard bits
ADMIN_FULL_ACCESS 132-177 0
ORGANIZATION_ADMIN 177-390 1 allowRead=true, allowCreate=true, allowEdit=true, allowDelete=true, viewAllRecords=true, modifyAllRecords=true
'member_default' 390-864 0
'viewer_readonly' 864-993 1 allowRead=true, allowCreate=false, allowEdit=false, allowDelete=false
MCP_AGENT_PERMISSION_SET_READ 993-1003 1 allowRead=true
MCP_AGENT_PERMISSION_SET_WRITE 1003-1018 1 allowRead=true, allowCreate=true, allowEdit=true, allowDelete=true
MCP_AGENT_PERMISSION_SET_RESTRICTED 1018-1049 0
ORGANIZATION_ADMIN_NO_BYPASS 1049-1074 0
TOTAL wildcard declarations in file: 4

member_default reads 0 while three sibling sets in the same run read 1, so
the zero is a reading and not a blind spot. Its only object spread is
...denyWritesOnManagedObjects(), whose keys are BETTER_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:

target setwildcardwhat the injected managed-table entry does there
organization_adminfull CRUD + viewAllRecords/modifyAllRecordsnarrows the wildcard
MCP write setfull CRUDnarrows the wildcard
viewer_readonlyread-onlybelt-and-suspenders over a wildcard that already denies (its own comment says so)
member_defaultnone since #5491it is the read grant itself — this set's access is exactly the objects it NAMES

Two sets read 0 in the census but do hold a wildcard, neither of them
member_default: admin_full_access takes its from
ADMIN_FULL_ACCESS_CAPABILITIES in @objectstack/spec, and
organization_admin_no_bypass is derived at module load by
deriveWallLessOrgAdmin. 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.

  1. Module docblock opening — "The default write-granting permission sets
    (...) grant CRUD via a '*' wildcard". Replaced by the per-set breakdown
    above, 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 forward
    from the sibling declaration.
  2. "Deliberately NOT covered" section — "are also wildcard-granted in these
    sets" now reads "reached by the wildcard in the target sets that carry one",
    and the viewAllRecords/modifyAllRecords argument names
    organization_admin, the only target set whose wildcard carries those bits.
  3. MANAGED_DENY_TARGET_SETS docblock — "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 are
harmless 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:

path : packages/plugins/plugin-security/src/managed-object-write-denies.ts
base ref : c54d4d3d7d0a7f3e6ec848dd0cb415ee35ebbb37
raw bytes : base=5664 working=6889 (differ: True)
non-comment chars : base=1372 working=1372
NON-COMMENT DIFF : EMPTY
CONTROL (one code line added to the working copy, comments untouched)
CONTROL non-comment diff : NON-EMPTY (comparator is live)

Syntactic parse, the one real failure mode of a docblock edit (a stray
*/ closing the block early), with a live-detector control:

 0 parse diagnostic(s) WORKING (after the docblock rewrite)
0 parse diagnostic(s) BASE c54d4d3d7 (control: known-good)
316 parse diagnostic(s) CONTROL (same file with a docblock closed early)
PARSE CHECK: PASS (and the detector is proven live by the control)

ESLint, repo-wide, CI's own commandpnpm lint = eslint . --no-inline-config
— exit 0 in 117s. The edited file is confirmed inside the receiving population
rather than assumed to be: --format json on 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 path
arguments; 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.ts imports six object definitions from
    ../src/objects/index.js plus the four generated bundles, and
    managed-object-write-denies.ts is named by neither — it is imported only by
    security-plugin.ts and three test files.
  • node scripts/check-test-completeness.mjs — exit 3, NOT MEASURED: it
    grades a saved turbo run test log and none was named. Its own text says
    this is the expected local branch, not a red.
  • pnpm check:dual-build-cjs-loads — not run; it needs a full build. See the
    declared narrowing below.

Declared narrowing: the dependency-closure build, this package's vitest run
and check:dual-build-cjs-loads were 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 --stat reading 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

…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
@claudeclaudeBot added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Sep 1, 2026
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

⚠️1 changed file(s) yielded no anchor (packages/plugins/plugin-security/src/managed-object-write-denies.ts), so the pages documenting them are NOT COVERED by this run — this is not a clean bill of health for those files. Nothing else in this diff resolved to a documentable surface (no symbol, route or SDK anchor derived from 1 changed package(s)).

What this run could not see
  • 1 changed file(s) yielded no anchor (packages/plugins/plugin-security/src/managed-object-write-denies.ts) — pages documenting those are invisible to this run
  • 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.

Coarse fallback — 14 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 e612dd0f5bac1313b4d8e2adb061521e210cb65fpackageMentionDocs.

@claude

claudeBot commented Sep 1, 2026

Copy link
Copy Markdown
ContributorAuthor

Out-of-scope finding filed while implementing this card, per AGENTS.md Prime Directive #10: #14029organization_admin_no_bypass holds a write-granting wildcard but is not in MANAGED_DENY_TARGET_SETS, so applyManagedWriteDenies walks past it and the registry-derived denies never reach it. Behaviour-class, deliberately NOT touched in this PR, which is prose only. Filed unassigned for triage.

Session: https://claude.ai/code/session_016ZC5rNQj3WEet5HAmmAkMs

Generated by Claude Code


Generated by Claude Code

@os-steve
os-steve marked this pull request as ready for review September 1, 2026 00:50
@os-steve
os-steve added this pull request to the merge queueSep 1, 2026
Merged via the queue into main with commit 0c95e34Sep 1, 2026
37 checks passed
@os-steve
os-steve deleted the claude/issue-13822-managed-write-denies-docblock branch September 1, 2026 01:20
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/sskip-changesetPR has no user-facing published change; bypasses the changeset gate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Stale docblock in managed-object-write-denies.ts still claims member_default grants CRUD via a '*' wildcard (removed by #5491)

2 participants

@os-steve@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

docs(plugin-security): correct the managed-write-denies docblock on member_default - #14028

Merged
os-steve merged 1 commit into
mainfrom
claude/issue-13822-managed-write-denies-docblock
Sep 1, 2026
Merged

docs(plugin-security): correct the managed-write-denies docblock on member_default#14028
os-steve merged 1 commit into
mainfrom
claude/issue-13822-managed-write-denies-docblock

Conversation

@claude

@claudeclaudeBot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Fixes#13822

Comments only. The module docblock of managed-object-write-denies.ts still
described member_default as granting CRUD through an objects['*']
wildcard. #5491 removed that wildcard, and the set's own declaration in
objects/default-permission-sets.ts now opens by saying the opposite.

Premise verified first, on today's origin/main

The 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 a
declaration and a declaration cannot hide behind one:

set (as declared) decl lines objects['*'] decls wildcard bits
ADMIN_FULL_ACCESS 132-177 0
ORGANIZATION_ADMIN 177-390 1 allowRead=true, allowCreate=true, allowEdit=true, allowDelete=true, viewAllRecords=true, modifyAllRecords=true
'member_default' 390-864 0
'viewer_readonly' 864-993 1 allowRead=true, allowCreate=false, allowEdit=false, allowDelete=false
MCP_AGENT_PERMISSION_SET_READ 993-1003 1 allowRead=true
MCP_AGENT_PERMISSION_SET_WRITE 1003-1018 1 allowRead=true, allowCreate=true, allowEdit=true, allowDelete=true
MCP_AGENT_PERMISSION_SET_RESTRICTED 1018-1049 0
ORGANIZATION_ADMIN_NO_BYPASS 1049-1074 0
TOTAL wildcard declarations in file: 4

member_default reads 0 while three sibling sets in the same run read 1, so
the zero is a reading and not a blind spot. Its only object spread is
...denyWritesOnManagedObjects(), whose keys are BETTER_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:

target setwildcardwhat the injected managed-table entry does there
organization_adminfull CRUD + viewAllRecords/modifyAllRecordsnarrows the wildcard
MCP write setfull CRUDnarrows the wildcard
viewer_readonlyread-onlybelt-and-suspenders over a wildcard that already denies (its own comment says so)
member_defaultnone since #5491it is the read grant itself — this set's access is exactly the objects it NAMES

Two sets read 0 in the census but do hold a wildcard, neither of them
member_default: admin_full_access takes its from
ADMIN_FULL_ACCESS_CAPABILITIES in @objectstack/spec, and
organization_admin_no_bypass is derived at module load by
deriveWallLessOrgAdmin. 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.

  1. Module docblock opening — "The default write-granting permission sets
    (...) grant CRUD via a '*' wildcard". Replaced by the per-set breakdown
    above, 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 forward
    from the sibling declaration.
  2. "Deliberately NOT covered" section — "are also wildcard-granted in these
    sets" now reads "reached by the wildcard in the target sets that carry one",
    and the viewAllRecords/modifyAllRecords argument names
    organization_admin, the only target set whose wildcard carries those bits.
  3. MANAGED_DENY_TARGET_SETS docblock — "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 are
harmless 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:

path : packages/plugins/plugin-security/src/managed-object-write-denies.ts
base ref : c54d4d3d7d0a7f3e6ec848dd0cb415ee35ebbb37
raw bytes : base=5664 working=6889 (differ: True)
non-comment chars : base=1372 working=1372
NON-COMMENT DIFF : EMPTY
CONTROL (one code line added to the working copy, comments untouched)
CONTROL non-comment diff : NON-EMPTY (comparator is live)

Syntactic parse, the one real failure mode of a docblock edit (a stray
*/ closing the block early), with a live-detector control:

 0 parse diagnostic(s) WORKING (after the docblock rewrite)
0 parse diagnostic(s) BASE c54d4d3d7 (control: known-good)
316 parse diagnostic(s) CONTROL (same file with a docblock closed early)
PARSE CHECK: PASS (and the detector is proven live by the control)

ESLint, repo-wide, CI's own commandpnpm lint = eslint . --no-inline-config
— exit 0 in 117s. The edited file is confirmed inside the receiving population
rather than assumed to be: --format json on 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 path
arguments; 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.ts imports six object definitions from
    ../src/objects/index.js plus the four generated bundles, and
    managed-object-write-denies.ts is named by neither — it is imported only by
    security-plugin.ts and three test files.
  • node scripts/check-test-completeness.mjs — exit 3, NOT MEASURED: it
    grades a saved turbo run test log and none was named. Its own text says
    this is the expected local branch, not a red.
  • pnpm check:dual-build-cjs-loads — not run; it needs a full build. See the
    declared narrowing below.

Declared narrowing: the dependency-closure build, this package's vitest run
and check:dual-build-cjs-loads were 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 --stat reading 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

…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
@claudeclaudeBot added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Sep 1, 2026
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

⚠️1 changed file(s) yielded no anchor (packages/plugins/plugin-security/src/managed-object-write-denies.ts), so the pages documenting them are NOT COVERED by this run — this is not a clean bill of health for those files. Nothing else in this diff resolved to a documentable surface (no symbol, route or SDK anchor derived from 1 changed package(s)).

What this run could not see
  • 1 changed file(s) yielded no anchor (packages/plugins/plugin-security/src/managed-object-write-denies.ts) — pages documenting those are invisible to this run
  • 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.

Coarse fallback — 14 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 e612dd0f5bac1313b4d8e2adb061521e210cb65fpackageMentionDocs.

@claude

claudeBot commented Sep 1, 2026

Copy link
Copy Markdown
ContributorAuthor

Out-of-scope finding filed while implementing this card, per AGENTS.md Prime Directive #10: #14029organization_admin_no_bypass holds a write-granting wildcard but is not in MANAGED_DENY_TARGET_SETS, so applyManagedWriteDenies walks past it and the registry-derived denies never reach it. Behaviour-class, deliberately NOT touched in this PR, which is prose only. Filed unassigned for triage.

Session: https://claude.ai/code/session_016ZC5rNQj3WEet5HAmmAkMs

Generated by Claude Code


Generated by Claude Code

@os-steve
os-steve marked this pull request as ready for review September 1, 2026 00:50
@os-steve
os-steve added this pull request to the merge queueSep 1, 2026
Merged via the queue into main with commit 0c95e34Sep 1, 2026
37 checks passed
@os-steve
os-steve deleted the claude/issue-13822-managed-write-denies-docblock branch September 1, 2026 01:20
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/sskip-changesetPR has no user-facing published change; bypasses the changeset gate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Stale docblock in managed-object-write-denies.ts still claims member_default grants CRUD via a '*' wildcard (removed by #5491)

2 participants

@os-steve@claude